【OpenFeign】okhttp3请求压缩请求与响应

OpenFeign默认使用的是Spring Cloud自带的HttpURLConnection进行HTTP请求,不支持对请求和响应进行压缩,需要做一些配置才能实现压缩。

  1. 添加压缩依赖:在项目中添加一个支持压缩的HTTP client,比如okhttp3,在pom.xml中添加如下依赖:
<dependency>
  <groupId>com.squareup.okhttp3groupId>
  <artifactId>okhttpartifactId>
  <version>4.4.0version>
dependency>

  1. 配置使用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()));
    }
}

  1. 添加压缩拦截器:在上面的配置中,添加了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);
    }
}

  1. 配置启用压缩:最后在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类型,只对满足这些类型的请求和响应进行压缩。

你可能感兴趣的:(技术问题,okhttp,java,开发语言)