Spring Cloud Feign 支持对请求和响应进行GZIP压缩,以提高通信效率。
fegin默认的Client对响应流不支持对gzip后的字节流进行解析,所以在序列化成对象时会存在解析问题。我们可以使用过滤器实现。开始实现。
1.依赖引入,pom文件添加feign-httpclient,将feign的http组件改为OkHttp
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> <version>2.2.0.RELEASE</version> </dependency> <dependency> <groupId>io.github.openfeign</groupId> <artifactId>feign-okhttp</artifactId> <version>10.7.4</version> </dependency>
复制
2.在application.properties中进行配置
ribbon.httpclient.enabled=false ribbon.okhttp.enabled=true feign.httpclient.enabled=false feign.okhttp.enabled=true//(使用okhttp) feign.compression.request.enabled=true//开启请求压缩 feign.compression.request.min-request-size=1024//设置请求大小,1024kb以上开始压缩 feign.compression.response.enabled=true//响应压缩 feign.compression.response.useGzipDecoder=true//响应解码
复制
在nacos里面配置:
ribbon: httpclient: enabled: false okhttp: enabled: true feign: httpclient: enabled: false okhttp: #使用okhttp enabled: true compression: request: #开启请求压缩 enabled: true #设置请求大小,1024kb以上开始压缩 min-request-size: 1024 response: #响应压缩 enabled: true #响应解码 useGzipDecoder: true
复制
3.配置启动类
@SpringCloudApplication //启用Fegin注解 @EnableFeignClients //启用过滤器,下面使用当前过滤器所在包名 @ServletComponentScan(basePackages = {"com.filter"}) public class Application { public static void main(String[] args) { SpringApplication application = new SpringApplication(Application.class); application.run(args); } }
复制
4.配置过滤器
@WebFilter(filterName="GzipFilter",urlPatterns="/*") @Slf4j public class GzipFilter implements Filter { @Override public void doFilter( ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain ) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) servletRequest; String contentEncoding = request.getHeader("Content-Encoding"); // 如果对内容进行了压缩,则解压 if (null != contentEncoding && contentEncoding.contains("gzip")){ request=new GzipRequestWrapper(request); } filterChain.doFilter(request,servletResponse); } public class GzipRequestWrapper extends HttpServletRequestWrapper { private HttpServletRequest request; public GzipRequestWrapper(HttpServletRequest request) { super(request); this.request = request; } @Override public ServletInputStream getInputStream() throws IOException { ServletInputStream stream = request.getInputStream(); 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 arg0) { // TODO Auto-generated method stub } }; return newStream; } catch (Exception e) { log.debug("ungzip content fail.", e); } return stream; } } }
复制