【Spring 框架接收GZIP个数数据处理】

Spring 框架接收GZIP个数数据处理

问题描述

上次处理了Feign的GZIP压缩问题,遇到了一个新的问题
经过了Feign转发一次后,请求的数据经过GZIP压缩了一次
有出现了一下错误信息

org.springframework.http.converter.HttpMessageNotReadableException: 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

这就说明了spring没有默认支持GZIP格式的解压缩

处理方式如下

package com.test.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.GZIPInputStream;

/**
 * 处理Gzip
 * @author Wei
 * @date 2022/11/16 9:43
 */
@Configuration
public class FilterConfig {
    /**
     * 注册 GzipFilter
     *
     * @return
     */
    @Bean
    public FilterRegistrationBean<Filter> filterRegistrationBean() {
        FilterRegistrationBean<Filter> registrationBean = new FilterRegistrationBean<>();
        registrationBean.setFilter(new GzipFilterConfig());

        List<String> urlPatterns = new ArrayList<>();
        urlPatterns.add("/*");
        registrationBean.setUrlPatterns(urlPatterns);

        return registrationBean;
    }

    @WebFilter(filterName = "gzipFilter", urlPatterns = "/")
    public static class GzipFilterConfig 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(javax.servlet.FilterConfig arg0){
        }
    }

    @Slf4j
    static class HttpServletRequestWrapper extends javax.servlet.http.HttpServletRequestWrapper {
        private final HttpServletRequest request;

        public HttpServletRequestWrapper(HttpServletRequest request) {
            super(request);
            this.request = request;
        }

        /**
         * 根据 request header 的 Content-Encoding 判断是否启用 gzip 解压数据流
         */
        @Override
        public ServletInputStream getInputStream() throws IOException {
            ServletInputStream stream = request.getInputStream();
            String contentEncoding = request.getHeader("Content-Encoding");
            if (null != contentEncoding && contentEncoding.contains("gzip")) {
                GZIPInputStream gzipInputStream = new GZIPInputStream(stream);
                try {
                    ByteArrayOutputStream bout = new ByteArrayOutputStream();
                    int len = -1;
                    byte[] buffer = new byte[128];
                    while((len = gzipInputStream.read(buffer))!=-1){
                        bout.write(buffer, 0, len);
                    }
                    ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
                    return new ServletInputStream() {
                        @Override
                        public int read(){
                            return bin.read();
                        }

                        @Override
                        public boolean isFinished() {
                            return false;
                        }

                        @Override
                        public boolean isReady() {
                            return false;
                        }

                        @Override
                        public void setReadListener(ReadListener readListener) {
                        }
                    };
                } catch (Exception e) {
                    log.error("decompression content fail", e);
                }finally{
                    try {
                        gzipInputStream.close();
                    } catch (Exception e) {
                        //
                    }
                }
            }

            return stream;
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值