RestTemplate处理HTTP状态码为400、500等错误码时,如何获取到其响应结果内容
一、问题的出现
最近在使用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(RequestApiUtil.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}¶me2={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