Feign 请求 响应的项目报错
JSON parse error: Illegal character ((CTRL-CHAR, code 31)): only regular white space (\r, \n, \t) is allowed between tokens; nested exception is com.fasterxml.jackson.core.JsonParseException: Illegal character ((CTRL-CHAR, code 31)): only regular white space (\r, \n, \t) is allowed between tokens at [Source: (PushbackInputStream); line: 1, column: 2]
还以为是Json使用的对应不上
截取请求的 InputStream 发现 是Gzip的乱码
原来是 Feign 发送的参数较多 自己启用了 Gzip压缩
但是接受时并没有判断 request.Header 里面有没有 Gzip
查了网上其他的回答
https://www.jianshu.com/p/df37eb5f2169
说是 SpringCloud版升级到Hoxton即可
但我的项目本身 SpringCloud 版本一直都是 Hoxton.SR8
还是不行
想了一下觉得 Feign应该只是封装调用请求的方式
毕竟 提供接口给Feign的方法也能被其他http请求调用
那就直接 搜索一下 Springboot gzip解压http 请求
编写Filter 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 /** * GZIP处理Filter */ @WebFilter(filterName = "httpServletGzipFilter", urlPatterns = "/") public class HttpServletGzipFilter implements Filter { @Override public void destroy() {} @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { chain.doFilter(new HttpServletRequestWrapper((HttpServletRequest) request), response); } @Override public void init(FilterConfig arg0) throws ServletException {} } @Slf4j class HttpServletRequestWrapper extends javax.servlet.http.HttpServletRequestWrapper { private HttpServletRequest request; public HttpServletRequestWrapper(HttpServletRequest request) { super(request); this.request = request; } /** * 根据 request header 的 Content-Encoding 判断是否启用 gzip 解压数据流 * @return * @throws IOException */ @Override public ServletInputStream getInputStream() throws IOException { ServletInputStream stream = request.getInputStream(); String contentEncoding = request.getHeader("Content-Encoding"); if (null != contentEncoding && contentEncoding.indexOf("gzip") != -1) { try { final GZIPInputStream gzipInputStream = new GZIPInputStream(stream); ServletInputStream newStream = new ServletInputStream() { @Override public int read() throws IOException { return gzipInputStream.read(); } @Override public boolean isFinished() { return false; } @Override public boolean isReady() { return false; } @Override public void setReadListener(ReadListener readListener) {} }; return newStream; } catch (Exception e) { log.error("uncompress content fail.", e); } } return stream; } }
注册Filter交给Spring管理 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 @Configuration public class HttpServletFilterConfig { /** * 注册 HttpServletFilter * * @return */ @Bean public FilterRegistrationBean filterRegistrationBean() { FilterRegistrationBean registrationBean = new FilterRegistrationBean(); registrationBean.setFilter(new HttpServletGzipFilter()); List<String> urlPatterns = new ArrayList<>(); urlPatterns.add("/*"); registrationBean.setUrlPatterns(urlPatterns); return registrationBean; } }
接下来按原先的 @RequestBody 即可正常获得数据
1 2 3 4 5 6 7 8 9 @MysdInterior @PostMapping ("place") @ApiOperation(value = "生成订单", notes = "提交订单加入数据库") public PlaceOrderVo place(@RequestBody PlaceOrderVo vo) { System.out.println(vo); log.info("mall api 生成订单 : place()"); log.info("参数 :" + String.valueOf(JSONUtil.parse(vo))); return vo; }