Spring RestTemplate错误处理:如何捕获服务端详细错误信息
如何捕获RestTemplate调用返回的详细错误响应体?
我用RestTemplate调用REST服务的代码如下:
ResponseEntity response = new RestTemplate().postForEntity(url, request, String.class);
当服务端返回错误时,会抛出这样的异常:
org.springframework.web.client.HttpClientErrorException: 400 Bad Request at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:85) at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:708) at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:661) at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:621) at org.springframework.web.client.RestTemplate.postForEntity(RestTemplate.java:415)
但用SOAPUI或Postman调用相同请求时,能拿到包含详细错误信息的XML响应:
<Errors> <Error ErrorCode="YFS10003" ErrorDescription="YFS:Invalid Order" ErrorUniqueExceptionId="10.148.201.9815264936514610000000000060" HttpCode="400"> <Attribute Name="ErrorDescription" Value="YFS:Invalid Order"/> <Attribute Name="ErrorUniqueExceptionId" Value="10.148.201.9815264936514610000000000060"/> <Attribute Name="ErrorCode" Value="YFS10003"/> <Attribute Name="HttpCode" Value="400"/> </Error> </Errors>
我想在代码里捕获并打印服务端返回的详细错误信息,而不是只得到通用的"400 Bad Request",请问能不能通过ResponseErrorHandler类实现这个需求?
当然可以!默认的DefaultResponseErrorHandler在遇到4xx或5xx状态码时,只会抛出包含状态码和通用描述的异常,完全没去读取响应体里的详细错误内容。我们可以自定义一个ResponseErrorHandler来解析响应体,把这些细节捞出来。
步骤1:自定义ResponseErrorHandler
写一个继承自DefaultResponseErrorHandler的自定义处理器,重写handleError方法来读取响应体:
import org.springframework.http.HttpStatus; import org.springframework.http.client.ClientHttpResponse; import org.springframework.web.client.DefaultResponseErrorHandler; import org.springframework.web.client.HttpClientErrorException; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; import java.util.stream.Collectors; public class CustomResponseErrorHandler extends DefaultResponseErrorHandler { @Override public void handleError(ClientHttpResponse response) throws IOException { // 读取响应体里的详细错误内容 String errorBody = new BufferedReader( new InputStreamReader(response.getBody(), StandardCharsets.UTF_8)) .lines() .collect(Collectors.joining("\n")); HttpStatus statusCode = response.getStatusCode(); // 抛出包含详细错误信息的异常,这样后面捕获时就能拿到完整内容 throw new HttpClientErrorException( statusCode, response.getStatusText(), errorBody.getBytes(StandardCharsets.UTF_8), StandardCharsets.UTF_8 ); } }
步骤2:给RestTemplate配置自定义错误处理器
别再直接new RestTemplate()就用了,先给它设置我们的自定义处理器:
RestTemplate restTemplate = new RestTemplate(); restTemplate.setErrorHandler(new CustomResponseErrorHandler()); try { ResponseEntity<String> response = restTemplate.postForEntity(url, request, String.class); // 处理正常响应逻辑 } catch (HttpClientErrorException e) { // 这里就能拿到服务端返回的详细错误XML了 System.out.println("详细错误信息:\n" + e.getResponseBodyAsString()); // 还能获取其他错误相关信息 System.out.println("HTTP状态码:" + e.getStatusCode()); System.out.println("状态描述:" + e.getStatusText()); }
额外说明
- 这个自定义处理器不仅能处理4xx的客户端错误,5xx的服务器错误也能覆盖到,因为我们继承了
DefaultResponseErrorHandler的错误判断逻辑,只是重写了错误处理的细节。 - 如果需要把XML解析成Java对象,你可以在捕获异常后,用Jackson或者JAXB把
e.getResponseBodyAsString()转换成对应的错误实体类,方便后续业务逻辑处理。
这样你就能拿到和Postman/SOAPUI完全一样的详细错误内容了!
内容的提问来源于stack exchange,提问作者himanshu gupta
相关产品推荐
相关产品推荐

