Feign远程调用数据量大时压缩导致转json失败

本文介绍了如何在SpringCloudFeign中启用GZIP压缩,解决默认Client对gzip响应流解析问题,通过引入feign-httpclient和feign-okhttp依赖,并配置启动类和自定义过滤器来实现请求和响应的自动解压缩。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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;
        }
    }
}

 

Feign是Netflix公司推出的一款轻量级的HTTP客户端,用于简化微服务之间的API调用。当使用Feign远程调用中遇到空指针异常(NullPointerException),通常意味着你在调用服务的过程中,某个预期不为null的字段、对象或参数被设置为了null。这可能由以下几个原因引起: 1. **参数缺失**:在Feign接口方法的定义中,如果某个方法参数被标记为非可选(@Nullable注解),但在实际调用没有提供值,可能会导致NullPointerException。 2. **请求处理错误**:如果Feign的实例化、配置或者网络连接出现问题,可能导致调用目标服务失败,返回null。 3. **服务响应异常**:目标服务在处理请求可能返回了无效或格式错误的数据,如果没有正确处理这些情况,也可能引发空指针异常。 4. **Java类型失败**:在从JSON或其他数据格式解析响应,如果类型失败,可能会抛出NullPointerException。 5. **缓存和重试机制**:如果Feign的缓存策略导致了旧的null响应被重新使用,或者重试机制在第一次尝试失败后返回了null,也会触发这个异常。 解决这个问题,你可以采取以下步骤: - **检查参数**:确保所有传递给Feign的方法参数都有正确的值。 - **日志追踪**:查看Feign的调用日志,找出引发异常的具体位置。 - **异常处理**:添加适当的异常处理代码,捕获并处理可能的空指针异常。 - **服务端检查**:确认目标服务是否稳定,并且返回的数据格式正确。 - **代码审查**:如果有多个开发者协作,可能是某个部分的代码修改引入了问题,需要进行代码审查。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

晒干的老咸鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值