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

RestTemplate返回200/201状态触发handleResponse/handleError问题排查

问题根因
  1. 首先纠正认知偏差:RestTemplate的handleResponse(URI url, HttpMethod method, ClientHttpResponse response)方法是所有HTTP请求响应的必经流程,并非只有响应异常时才会执行。该方法内部会调用绑定的ResponseErrorHandler的hasError方法判定响应是否为错误,只有hasError返回true时,才会继续调用handleError方法执行错误处理逻辑。因此返回200 Success时进入该方法、流转到自定义ErrorHandler类是符合框架设计的正常流程,此时因为hasError返回false,不会触发后续错误抛出逻辑。
  2. 返回201 Created时触发异常的核心原因是自定义错误处理器判断逻辑有误:
    实现的hasError方法将「状态码不等于HttpStatus.OK」作为错误判定条件,这意味着除了200之外的所有状态码——包括HTTP标准中属于成功响应范畴的201 Created、204 No Content等2xx状态码,都会被判定为错误响应,进而进入handleError方法。而handleError的switch分支没有覆盖201状态,最终走default分支抛出了INTERNAL_SERVER_ERROR对应的业务异常。
解决方案

根据业务语义选择对应修改方式即可:

  • 方案1(符合HTTP标准规范,推荐):将所有2xx类状态码都判定为成功响应,修改hasError逻辑:
@Override
public boolean hasError(ClientHttpResponse clientHttpResponse) throws IOException {
    HttpStatus statusCode = clientHttpResponse.getStatusCode();
    // 非2xx范围的状态码才判定为错误
    return !statusCode.is2xxSuccessful();
}
  • 方案2(适配仅200算成功的特殊业务场景):保留现有hasError判断逻辑,在handleError的switch分支中补全所有非200但需要特殊处理的状态码,不要让其走default分支抛出500错误,例如补充201的对应处理逻辑:
// 其他已有分支不变
case CREATED: // 201 Created
    // 根据业务需求实现对应逻辑,例如直接返回不抛异常、或抛出匹配的业务异常
    break;
default:
    throw new BusinessException(errMessage, ErrorResponse.INTERNAL_SERVER_ERROR);

额外优化点:外层调用restTemplate.exchange时的catch块存在冗余逻辑,错误状态码的判断、对应BusinessException的抛出已经在自定义ErrorHandler中实现,外层不需要重复判断状态码,直接捕获抛出的BusinessException做后续业务处理即可。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 16:21:21