OpenFeign默认使用的是Spring Cloud自带的HttpURLConnection进行HTTP请求,不支持对请求和响应进行压缩,需要做一些配置才能实现压缩。
- 添加压缩依赖:在项目中添加一个支持压缩的HTTP client,比如okhttp3,在pom.xml中添加如下依赖:
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.4.0</version>
</dependency>
- 配置使用okhttp3:在Feign的配置类中增加一个配置,将默认的Apache
HttpClient替换为okhttp3,以实现压缩,示例如下:
@Configuration
public class FeignConfig {
@Bean
public OkHttpClient okHttpClient() {
return new OkHttpClient.Builder()
.addInterceptor(new RequestCompressionInterceptor())
.addInterceptor(new ResponseCompressionInterceptor())
.build();
}
@Bean
public Feign.Builder feignBuilder() {
return Feign.builder().client(new OkHttpClient(okHttpClient()));
}
}
- 添加压缩拦截器:在上面的配置中,添加了RequestCompressionInterceptor和ResponseCompressionInterceptor拦截器,分别用于对请求和响应进行压缩。这两个拦截器需要自己实现。
public class RequestCompressionInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Request originalRequest = chain.request();
// 不需要压缩的URI
if (shouldCompress(originalRequest)) {
// 添加压缩请求头
Request compressedRequest = originalRequest.newBuilder()
.header("Accept-Encoding", "gzip")
.method(originalRequest.method(), gzip(originalRequest.body()))
.build();
return chain.proceed(compressedRequest);
}
return chain.proceed(originalRequest);
}
private boolean shouldCompress(Request request) {
// 自定义自己需要压缩的URI
String uri = request.url().uri().toString();
return !uri.contains("/no_compress");
}
private RequestBody gzip(RequestBody body) throws IOException {
BufferedSink gzipSink = Okio.buffer(new GzipSink(Okio.sink(new ByteArrayOutputStream())));
BufferedSink buffer = Okio.buffer(gzipSink);
body.writeTo(buffer);
buffer.close();
return RequestBody.create(body.contentType(), gzipSink.buffer().readByteArray());
}
}
public class ResponseCompressionInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Response originalResponse = chain.proceed(chain.request());
// 响应头的Content-Encoding中包含gzip,说明响应需要解压
if ("gzip".equalsIgnoreCase(originalResponse.header("Content-Encoding"))) {
return originalResponse.newBuilder()
.body(gzip(originalResponse))
.build();
}
return originalResponse;
}
private ResponseBody gzip(Response response) throws IOException {
BufferedSource source = Okio.buffer(new GzipSource(response.body().source()));
return ResponseBody.create(response.body().contentType(), response.body().contentLength(), source);
}
}
- 配置启用压缩:最后在application.properties文件中配置启用压缩:
feign.compression.request.enabled=true
feign.compression.request.mime-types=text/*,application/json
feign.compression.response.enabled=true
在上面的配置中,feign.compression.request.enabled和feign.compression.response.enabled均设置为true,表示启用请求和响应的压缩。同时还配置了请求和响应的Content-Type类型,只对满足这些类型的请求和响应进行压缩。