如何从Spring Boot的@RestController响应中移除Transfer-Encoding: chunking?
解决Spring Boot REST API分块编码导致老旧客户端解析失败的问题
你的问题核心是嵌入式容器(如默认的Tomcat)自动启用了分块编码(Transfer-Encoding: chunked),导致响应首尾出现块大小数字,老旧客户端无法识别。不需要逐个修改控制器,以下是几种全局生效的简便方案:
方案1:通过Spring Boot配置强制禁用分块编码
直接在application.properties或application.yml中配置容器参数,让响应优先使用固定长度编码:
针对Tomcat(默认容器)
在application.properties添加:
# 设置输出缓冲区大小,当响应内容小于该值时,Tomcat会自动用Content-Length替代分块 server.tomcat.output-buffer-size=1048576 # 禁用自动分块的相关配置 server.tomcat.send-file-size=-1
或者用application.yml:
server: tomcat: output-buffer-size: 1048576 send-file-size: -1
说明:缓冲区大小可根据你的API响应平均大小调整,比如设为1MB或更大,确保大多数响应能被一次性输出,触发固定长度编码。
方案2:全局过滤器统一处理所有API响应
创建一个过滤器,强制清除分块编码头,对所有指定路径的请求生效:
1. 实现过滤器类
import javax.servlet.*; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class DisableChunkingFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletResponse httpResp = (HttpServletResponse) response; // 清空分块编码头,强制容器使用固定长度 httpResp.setHeader("Transfer-Encoding", ""); chain.doFilter(request, httpResp); } }
2. 注册过滤器到Spring容器
import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class WebFilterConfig { @Bean public FilterRegistrationBean<DisableChunkingFilter> disableChunkingFilter() { FilterRegistrationBean<DisableChunkingFilter> regBean = new FilterRegistrationBean<>(); regBean.setFilter(new DisableChunkingFilter()); regBean.addUrlPatterns("/api/*"); // 替换成你的API根路径 return regBean; } }
方案3:Spring MVC全局拦截器
和过滤器原理类似,用拦截器统一处理响应头:
1. 实现拦截器类
import org.springframework.web.servlet.HandlerInterceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class DisableChunkingInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { response.setHeader("Transfer-Encoding", ""); return true; } }
2. 注册拦截器
import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class WebMvcConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new DisableChunkingInterceptor()) .addPathPatterns("/api/**"); // 匹配你的API路径 } }
补充说明
- 如果使用Jetty或Undertow作为嵌入式容器,配置方式略有不同:
- Jetty:设置
server.jetty.output-buffer-size - Undertow:设置
server.undertow.max-buffer-size
- Jetty:设置
- 手动设置
Transfer-Encoding头无效的原因是,嵌入式容器会根据自身规则(比如响应大小、缓冲区配置)覆盖这个头,所以必须通过容器配置或全局拦截/过滤的方式强制禁用分块。
内容的提问来源于stack exchange,提问作者Artuto
相关产品推荐
相关产品推荐

