You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot解压GZIP请求后无法触发JSON接收接口怎么办?

解决方案:Angular/Spring Boot GZIP压缩请求适配问题

你遇到的Content type '' not supported错误,核心原因有两个:一是Angular端发送Blob时未指定正确的Content-Type,二是Spring Boot的请求包装器没有保留原请求的Content-Type头,导致Spring无法识别请求格式。以下是具体修复步骤:


1. 修正Angular端请求配置

创建Blob时必须显式指定application/json类型,同时确保Content-Encoding和Content-Type头都正确设置:

const jsonBody = JSON.stringify(request.body);
const compressedBody = pako.gzip(jsonBody);
// 创建Blob时指定Content-Type为application/json
const blobCompressedBody = new Blob([compressedBody], { type: 'application/json' });
const newRequest = request.clone({
  headers: request.headers
    .append('Content-Encoding', 'gzip')
    .set('Content-Type', 'application/json'),
  body: blobCompressedBody
});

2. 完善Spring Boot的请求包装器

你的GzippedInputStreamWrapper需要重写getContentType()和相关头信息方法,确保原请求的内容类型不丢失:

public class GzippedInputStreamWrapper extends HttpServletRequestWrapper {
    private final InputStream inputStream;

    public GzippedInputStreamWrapper(HttpServletRequest request) throws IOException {
        super(request);
        try {
            this.inputStream = new GZIPInputStream(request.getInputStream());
        } catch (EOFException e) {
            // 空输入流时返回空字节流
            this.inputStream = new ByteArrayInputStream(new byte[0]);
        } catch (Exception e) {
            e.printStackTrace();
            // 异常时回退到原输入流
            this.inputStream = request.getInputStream();
        }
    }

    @Override
    public InputStream getInputStream() throws IOException {
        return inputStream;
    }

    // 重写该方法,返回原请求的Content-Type
    @Override
    public String getContentType() {
        return super.getContentType();
    }

    // 确保Content-Type头能被正确获取
    @Override
    public String getHeader(String name) {
        if ("Content-Type".equalsIgnoreCase(name)) {
            return super.getHeader(name);
        }
        return super.getHeader(name);
    }
}

3. 修正过滤器的doFilter逻辑

仅对带有Content-Encoding: gzip头的请求使用包装器,避免影响正常非压缩请求:

public class GzipRequestFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        String contentEncoding = httpRequest.getHeader("Content-Encoding");
        
        if (contentEncoding != null && contentEncoding.equalsIgnoreCase("gzip")) {
            chain.doFilter(new GzippedInputStreamWrapper(httpRequest), response);
        } else {
            chain.doFilter(request, response);
        }
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {}

    @Override
    public void destroy() {}
}

4. 注册过滤器到Spring Boot

通过@Component注解直接注册过滤器:

@Component
public class GzipRequestFilter implements Filter {
    // 上述doFilter等方法
}

修复原理

  • Angular端指定Blob的type后,请求的Content-Type会被正确设置为application/json,Content-Encoding: gzip则告诉后端需要解压内容。
  • Spring的请求包装器重写相关方法后,Spring MVC能正确识别请求的内容类型,匹配控制器的consumes = "application/json"条件,自动将解压后的JSON映射到UserDTO参数。

内容的提问来源于stack exchange,提问作者Ana Belén González Villalba

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 22:00:56