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

Spring Boot 1.5.9中禁用@RestController的Transfer-Encoding,自动加Content-Length

全局禁用分块编码并自动添加Content-Length的解决方案(Spring Boot 1.5.9.RELEASE)

我来帮你搞定这个问题——不用逐个修改控制器端点为ResponseEntity,就能全局禁用分块编码,让响应自动带上Content-Length头,这里有两个实用的通用方案:

方案一:通过Tomcat容器配置强制关闭分块编码

Spring Boot 1.5.x默认用Tomcat当嵌入式容器,我们可以自定义Tomcat容器工厂,修改Connector参数来强制禁用分块传输:

import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class TomcatConfig {

    @Bean
    public TomcatEmbeddedServletContainerFactory tomcatEmbeddedServletContainerFactory() {
        TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory();
        factory.addConnectorCustomizers(connector -> {
            // 开启这个配置后,Tomcat会自动计算响应体长度并添加Content-Length,同时禁用分块
            connector.setProperty("disableChunking", "true");
        });
        return factory;
    }
}

这个配置对所有端点生效,只要你的响应体(比如JSON)能被提前计算长度,Tomcat就会自动帮你处理好Content-Length头,再也不会返回Transfer-Encoding: chunked了。

方案二:自定义ResponseBodyAdvice统一处理响应

如果你的应用以后可能切换容器(比如从Tomcat换成Jetty),或者需要更灵活的控制逻辑,可以用ResponseBodyAdvice拦截所有@ResponseBody的响应,手动处理长度和分块:

import org.springframework.core.MethodParameter;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;

@ControllerAdvice
public class DisableChunkingAdvice implements ResponseBodyAdvice<Object> {

    @Override
    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
        // 对所有@ResponseBody的接口生效,也可以在这里过滤特定的控制器或方法
        return true;
    }

    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
                                  Class<? extends HttpMessageConverter<?>> selectedConverterType,
                                  ServerHttpRequest request, ServerHttpResponse response) {
        if (response instanceof ServletServerHttpResponse) {
            HttpServletResponse servletResponse = ((ServletServerHttpResponse) response).getServletResponse();
            // 设置足够大的缓冲区,确保响应体能被完整缓存,避免分块
            servletResponse.setBufferSize(1024 * 1024);
            // 清空分块编码的响应头
            servletResponse.setHeader("Transfer-Encoding", "");

            try {
                // 把响应体转换成字节数组,计算长度
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                HttpMessageConverter<Object> converter = selectedConverterType.newInstance();
                converter.write(body, selectedContentType, new ServerHttpResponse() {
                    @Override
                    public OutputStream getBody() throws IOException {
                        return baos;
                    }

                    @Override
                    public HttpHeaders getHeaders() {
                        return new HttpHeaders();
                    }
                });
                byte[] bodyBytes = baos.toByteArray();
                // 设置Content-Length头
                servletResponse.setContentLength(bodyBytes.length);
                // 返回字节数组,让容器直接输出
                return bodyBytes;
            } catch (Exception e) {
                // 万一出问题,就 fallback 到默认处理逻辑
                return body;
            }
        }
        return body;
    }
}

一些注意点

  1. 方案一只对Tomcat生效,如果用Jetty或Undertow,得对应调整容器配置。比如Jetty可以在HttpConfiguration里设置setSendContentLength(true)并禁用分块。
  2. 如果你的接口有流式响应(比如返回InputStream),分块编码是必须的,这种情况可以在supports方法里排除这些接口。
  3. 这两个方案都适配Spring Boot 1.5.9.RELEASE的稳定API,不用担心兼容性问题。

内容的提问来源于stack exchange,提问作者Raashith

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 07:28:13