RestTemplate处理HTTP状态码为400、500等错误码时,如何获取到其响应结果内容

发布时间 2023-07-19 17:37:05作者: 苹果芒

一、问题的出现

最近在使用RestTemplate发送HTTP请求时,服务端发送回来的响应结果中,HTTP响应码为400、500之类的,RestTemplate默认不处理这类响应结果,直接抛异常。但是,该请求的响应结果内容却是我需要用到的,因为我需要通过该请求的响应结果内容,告诉用户远程调用接口时,出现错误时问题是什么,以及通过请求返回的自定义结果集,来进行其他操作。

现在我们开发中,不管用户执行该请求是否成功,返回的HTTP状态码都是200,但是会在返回的自定义结果集中的code、message去体现具体操作成功与否。

但是该远程服务器返回的结果不太一样,如果用户的操作失败,首先返回的HTTP状态码是400之类的,但是返回的结果是自定义的结果集。

这就导致了,如果不对RestTemplate进行任何配置的话,RestTemplate在遇到HTTP状态码为400、500之类的状态码,直接就抛异常了,就算请求有返回的结果集,我也拿不到.

二、解决方案

给RestTemplate设置一个自定义的ResponeErrorHandler

/**
 * RestTemplate配置类
 */
@Slf4j
@Configuration
public class RestTemplateConfig {
 
    /**
     * 常用远程调用RestTemplate
     * @return restTemplate
     */
    @Bean("restTemplate")
    public RestTemplate restTemplate(){
        RestTemplate restTemplate = new RestTemplate();
        restTemplate.setErrorHandler(new AcceptResponseErrorHandler());
        return restTemplate ;
    }
 
    /**
     * 使RestTemplate能够对响应的错误消息不进行处理
     * 如:当响应码为400、500等错误时,能够不进行处理,最终用户可以获取到body数据
     */
    private static class AcceptResponseErrorHandler implements ResponseErrorHandler {
 
        @Override
        public boolean hasError(ClientHttpResponse response) throws IOException {
            return false;
        }
 
        @Override
        public void handleError(ClientHttpResponse response) throws IOException {
 
        }
}

至此,通过以上配置,RestTemplate在遇到HTTP状态码为400、500错误码时,能够不抛出异常,开发者也能够对其中的响应结果进行处理。

以下,将简单地对源码进行分析,展现,为什么RestTemplate在遇到HTTP状态码为400、500错误码时,会抛出异常。

然后就是在需要用到restTemplate的地方注入就行了:

@Service
public class RequestApiUtil {
    private org.slf4j.Logger logger = LoggerFactory.getLogger(TestController.class);

    //    private RestTemplate restTemplate = new RestTemplate();//RestTemplate默认不处理HTTP响应码为400、500这类响应结果,直接抛异常
    //注入restTemplate bean
    @Resource(name = "myRestTemplate")
    private RestTemplate restTemplate;

    public JSONObject getApi(String url, Map<String, String> parameters) {
        try {
            logger.info("Start to invoke api,url is {} , Parameters is {}", url, parameters.toString());
            //Set url, restTemplate请求的url后面要有占位符
            StringBuffer sb = new StringBuffer(url);
            sb = sb.append("?");
//        sb=sb.append("?parame1={parame1}&parame2={parame2}");//get请求得参数,需要先占位 才能请求成功 
    for (String key : parameters.keySet()) {
    sb.append(key + "={" + key + "}&"); 
    } 
    sb = new StringBuffer(sb.substring(0, sb.lastIndexOf("&"))); 
    String response = restTemplate.getForObject(
      sb.toString(),//获取资源的地址 
      String.class,//返回类型设为String  
      parameters 
    );     JSONObject body
= JSONObject.parseObject(response);     Integer code = body.getInteger("code");     String msg = body.getString("msg");     logger.info("Invoke api,response code is {},msg is {}", code, msg);     return body;     }catch (Exception e) {        logger.error("Invokeapi coverage api failed!respone is {}", e.toString());
       return null;    } }

 参考:https://blog.csdn.net/Staba/article/details/124405234