Spring REST中RestClientResponseException缺失响应体的解决方法
解决RestTemplate调用时无法获取自定义ErrorObject响应体的问题
这个问题我之前也碰到过,核心原因是RestClientResponseException虽然包含了响应体,但默认不会自动帮你反序列化为ErrorObject,需要我们手动处理或者配置RestTemplate的错误处理器来实现。下面给你两种可行的方案:
方案一:手动从异常中提取响应体并反序列化
RestClientResponseException提供了getResponseBodyAsString()方法,可以直接拿到响应体的JSON字符串,然后用Jackson的ObjectMapper手动转成ErrorObject。代码示例如下:
try { ResponseEntity<WhateverObject> entity = restTemplate.exchange(url, HttpMethod.POST, getBaseHeadersAsHttpEntity(), WhateverObject.class); // 正常业务逻辑 } catch (RestClientResponseException e) { ObjectMapper objectMapper = new ObjectMapper(); try { // 把响应体字符串反序列化为ErrorObject ErrorObject errorObject = objectMapper.readValue(e.getResponseBodyAsString(), ErrorObject.class); // 这里就可以使用errorObject里的name、status、message了 System.out.println("错误信息:" + errorObject.getMessage()); } catch (JsonProcessingException ex) { // 处理反序列化失败的情况,比如响应体不是预期的JSON格式 ex.printStackTrace(); } }
这种方法简单直接,不需要修改RestTemplate的配置,适合快速解决问题。
方案二:自定义RestTemplate的错误处理器
如果希望每次调用都自动解析错误响应体,不用每次都手动反序列化,可以自定义ResponseErrorHandler,让RestTemplate在抛出异常时直接携带解析好的ErrorObject。
步骤1:创建自定义异常类
用来包装错误状态码和ErrorObject:
public class CustomRestClientException extends RuntimeException { private HttpStatus statusCode; private ErrorObject errorObject; public CustomRestClientException(HttpStatus statusCode, ErrorObject errorObject) { super(errorObject.getMessage()); this.statusCode = statusCode; this.errorObject = errorObject; } // 生成getter方法 public HttpStatus getStatusCode() { return statusCode; } public ErrorObject getErrorObject() { return errorObject; } }
步骤2:实现自定义ResponseErrorHandler
继承默认的DefaultResponseErrorHandler,重写错误处理逻辑:
import org.springframework.http.client.ClientHttpResponse; import org.springframework.web.client.DefaultResponseErrorHandler; import com.fasterxml.jackson.databind.ObjectMapper; import java.io.IOException; import java.nio.charset.StandardCharsets; import org.springframework.util.StreamUtils; import org.springframework.http.HttpStatus; public class CustomResponseErrorHandler extends DefaultResponseErrorHandler { private final ObjectMapper objectMapper = new ObjectMapper(); @Override public void handleError(ClientHttpResponse response) throws IOException { HttpStatus statusCode = HttpStatus.resolve(response.getRawStatusCode()); if (statusCode != null && hasError(statusCode)) { // 读取响应体字符串 String responseBody = StreamUtils.copyToString(response.getBody(), StandardCharsets.UTF_8); // 反序列化为ErrorObject ErrorObject errorObject = objectMapper.readValue(responseBody, ErrorObject.class); // 抛出自定义异常,携带解析后的ErrorObject throw new CustomRestClientException(statusCode, errorObject); } // 其他情况交给父类处理 super.handleError(response); } }
步骤3:配置RestTemplate使用自定义错误处理器
在创建RestTemplate的时候设置我们的错误处理器:
RestTemplate restTemplate = new RestTemplate(); restTemplate.setErrorHandler(new CustomResponseErrorHandler());
之后调用接口时,直接捕获CustomRestClientException就能拿到解析好的ErrorObject了:
try { ResponseEntity<WhateverObject> entity = restTemplate.exchange(url, HttpMethod.POST, getBaseHeadersAsHttpEntity(), WhateverObject.class); // 正常业务逻辑 } catch (CustomRestClientException e) { ErrorObject errorObject = e.getErrorObject(); System.out.println("错误名称:" + errorObject.getName()); System.out.println("状态码:" + errorObject.getStatus()); System.out.println("错误消息:" + errorObject.getMessage()); }
注意事项
- 确保你的
ErrorObject类有正确的getter/setter方法,或者使用@Data注解(Lombok),否则Jackson无法正常反序列化。 - 确认服务器返回的响应头
Content-Type是application/json,并且RestTemplate的消息转换器中包含MappingJackson2HttpMessageConverter(Spring Boot默认会配置)。
内容的提问来源于stack exchange,提问作者victorio
相关产品推荐
相关产品推荐

