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

使用RestTemplate打印异常时如何输出完整的错误响应信息?

RestTemplate调用HTTP接口错误响应体截断问题

问题背景

我们的应用基于Spring Boot 2.3.10.RELEASE版本开发,通过RestTemplate调用大量REST API。当接口返回4xx或5xx类HTTP错误码并携带响应体时,日志中无法输出完整的响应体内容。

最小可复现示例

import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestTemplate;

@Slf4j
public class RestTemplateTest {

    @Test
    void shouldPrintErrorForRestTemplate() {
        RestTemplate restTemplate = new RestTemplate();
        try {
            restTemplate.getForEntity("http://hellosmilep.free.beeceptor.com/error/notfound", String.class);
        } catch (Exception e) {
            log.error("Error calling REST API", e);
        }
    }
}

实际日志输出

10:28:11.347 [main] ERROR com.smilep.java.webapp.RestTemplateTest - Error calling REST API
org.springframework.web.client.HttpClientErrorException$NotFound: 404 Not Found: [{
  "glossary": {
    "title": "example glossary",
    "GlossDiv": {
      "title": "S",
      "GlossList": {
        "GlossEntry": {
          "ID": "SGML",
          "SortAs": "SGML",
          "Glo... (593 bytes)]
...(堆栈省略)

现有方案痛点

目前可以通过如下代码手动打印完整响应体,但需要在大量业务类中添加重复的样板代码,跨应用适配成本很高:

if(e instanceof HttpClientErrorException) {
    log.error("response body : " + ((HttpClientErrorException) e).getResponseBodyAsString());
}

疑问点

  • 有没有办法在直接打印Exception对象时就输出完整的错误响应体,不会出现... (xxx bytes)的截断?
  • Java中是否存在默认的错误日志消息长度限制,超过就会自动截断?如果有,如何修改该限制?

相关更新

已向Spring团队提交Issue建议将该日志长度限制改为可配置项,目前官方已完全移除该限制,改动将在后续Spring版本上线。

问题解答

1. 截断的根本原因

Java本身的日志框架(SLF4J、Logback、Log4j2等)默认没有异常消息长度限制,该截断是Spring框架RestTemplate的内部实现导致的:HttpClientErrorException/HttpServerErrorException构造异常消息时,默认只会读取前200字节的响应体拼接到message字段,超出部分就会生成... (xxx bytes)的截断提示,因此直接打印异常时看不到完整内容。

2. 无需修改业务代码的全局解决方案

通过自定义全局ResponseErrorHandler就可以实现直接打印异常就输出完整响应体,适配所有使用RestTemplate的业务场景,步骤如下:

  1. 实现自定义错误处理器,捕获异常时用完整响应体重写异常消息:
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatusCode;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.web.client.DefaultResponseErrorHandler;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.HttpServerErrorException;

import java.io.IOException;
import java.nio.charset.StandardCharsets;

public class FullResponseBodyErrorHandler extends DefaultResponseErrorHandler {
    @Override
    public void handleError(ClientHttpResponse response) throws IOException {
        // 读取完整响应体
        byte[] body = getResponseBody(response);
        String responseBody = new String(body, StandardCharsets.UTF_8);
        HttpStatusCode statusCode = response.getStatusCode();
        String statusText = response.getStatusText();
        HttpHeaders headers = response.getHeaders();
        try {
            super.handleError(response);
        } catch (HttpClientErrorException | HttpServerErrorException e) {
            // 抛出带完整响应体的新异常,覆盖原有截断消息
            if (e instanceof HttpClientErrorException) {
                throw new HttpClientErrorException(statusCode, statusText + ": " + responseBody, headers, body, StandardCharsets.UTF_8);
            } else {
                throw new HttpServerErrorException(statusCode, statusText + ": " + responseBody, headers, body, StandardCharsets.UTF_8);
            }
        }
    }
}
  1. Spring Boot项目中全局配置RestTemplate使用该错误处理器:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class RestTemplateConfig {
    @Bean
    public RestTemplate restTemplate() {
        RestTemplate restTemplate = new RestTemplate();
        restTemplate.setErrorHandler(new FullResponseBodyErrorHandler());
        return restTemplate;
    }
}

配置完成后,所有通过依赖注入获取的RestTemplate抛出的HTTP异常都会携带完整响应体,业务代码直接打印异常就可以看到完整内容,不需要做任何修改。

3. 官方版本适配方案

Spring官方移除响应体截断限制的改动已经在Spring Framework 5.3.22+、6.0.0+版本正式生效,升级Spring Boot版本到2.7.2+或者3.x及以上版本,默认就不会出现响应体截断问题,不需要额外配置。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 10:27:03