Spring Boot如何配置自动解压Content-Encoding gzip请求
问题根因说明
- 你配置的
server.compression.enabled=true仅对HTTP响应生效,作用是把服务端返回的响应体压缩后发给客户端,完全不涉及入站请求体的解压逻辑,这就是gzip压缩的二进制请求体直接传给Jackson报JSON解析错误的直接原因。 - 你遇到的
CTRL-CHAR, code 31错误是gzip压缩数据的魔数开头字节,刚好证明请求体根本没经过解压就被JSON解析器读取了。
HTTP/2与gzip请求解压的关系
两者没有任何关联,开启server.http2.enabled=true不会自动支持gzip请求解压:
- HTTP/2协议内置的压缩能力仅针对HTTP请求/响应头(即HPACK算法),和请求体的
Content-Encoding编码处理逻辑完全独立,不管用HTTP/1.1还是HTTP/2,请求体解压都需要单独配置。
嵌入式Tomcat场景开启gzip请求自动解压的方案
Spring Boot用嵌入式Tomcat时,Tomcat本身已经内置了gzip/deflate格式请求体的解压能力,只是默认关闭,不需要额外引入依赖或者自定义过滤器,直接开启对应配置即可。
方式1:配置文件直接配置(Spring Boot 2.1及以上版本支持)
在application.yml中添加如下配置:
server: tomcat: connector: additional-attributes: # 开启Tomcat对入站请求体的解压支持 allowCompression: "true" # 触发解压的最小请求体大小,单位字节,设为0代表所有大小请求都处理 compressionMinSize: "0"
如果是properties格式配置:
server.tomcat.connector.additional-attributes.allowCompression=true server.tomcat.connector.additional-attributes.compressionMinSize=0
方式2:自定义Tomcat连接器配置(兼容所有Spring Boot版本)
如果配置文件方式不生效,可以注册一个Tomcat连接器自定义器来开启参数:
import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class TomcatRequestConfig { @Bean public TomcatConnectorCustomizer enableGzipRequestDecompress() { return connector -> { connector.setAllowCompression(true); connector.setCompressionMinSize(0); }; } }
验证方法
配置完成后重启应用,直接用你之前写的测试脚本发起请求即可:
echo '{"field1":"hello","field2":"there"}' > request.json gzip -f request.json curl -u user:password -H "Content-Encoding: gzip" -H 'Content-Type:application/json;charset=utf8' --data-binary @request.json.gz http://localhost:8100/some/path
接口会正常接收解析JSON参数,不会再报JSON解析控制字符的错误。
注意:如果你的应用前部署了Nginx、Spring Cloud Gateway等反向代理/网关层,需要确认网关没有提前解压请求体并移除
Content-Encoding: gzip请求头,避免出现重复解压或者解压逻辑不生效的问题。
内容的提问来源于stack exchange,提问作者Willem
相关产品推荐
相关产品推荐

