解决RestTemplate 请求接收自定义400+ 或500+错误

网友投稿 1165 2022-12-17

解决RestTemplate 请求接收自定义400+ 或500+错误

解决RestTemplate 请求接收自定义400+ 或500+错误

目录RestTemplate 请求接收自定义400+ 或500+错误场景原因解决办法自定义RestTemplate的ResponseErrorHandlerSpring框架中的RestTemplate处理ClientHttpResponse的方式并不想让它抛异常无法使用IOC注入的场景下

RestTemplate 请求接收自定义400+ 或500+错误

场景

当服务端自定义400错误返回体时,使用restTemplate 请求接收不到消息体。而我正想根据不同的错误信息做不同的操作。

原因

restTemplate 内置了自己的处理异常的方法ResponseErrorHandler去处理异常

protected void handleResponse(URI url, HttpMethod method, ClientHttpResponse response) throws IOException {

ResponseErrorHandler errorHandler = getErrorHandler();

boolean hasError = errorHandler.hasError(response);

if (logger.isDebugEnabled()) {

try {

logger.debug(method.name() + " request for \"" + url + "\" resulted in " +

response.getRawStatusCode() + " (" + response.getStatusText() + ")" +

(hasError ? "; invoking error handler" : ""));

}

catch (IOException ex) {

// ignore

}

}

if (hasError) {

errorHandler.handleError(response);

}

}

当接收到CLIENT_ERROR 或 SERVER_ERROR 时,直接抛异常

@Override

public void handleError(ClientHttpResponse response) throws IOException {

HttpStatus statusCode = getHttpStatusCode(response);

switch (statusCode.series()) {

caAovwzIbjqse CLIENT_ERROR:

throw new HttpClientErrorException(statusCode, response.getStatusText(),

response.getHeaders(), getResponseBody(response), getCharset(response));

case SERVER_ERROR:

throw new HttpServerErrorException(statusCode, response.getStatusText(),

response.getHeaders(), getResponseBody(response), getCharset(response));

default:

throw new RestClientException("Unknown status code [" + statusCode + "]");

}

}

解决办法

自定义异常处理器,对响应的错误信息不进行处理

public class FacePlusThrowErrorHandler implements ResponseErrorHandler {

@Override

public boolean hasError(ClientHttpResponse response) throws IOException {

return false;

}

@Override

public void handleError(ClientHttpResponse response) throws IOException {

}

}

之后在bean 注入时,设置restTemplate 默认异常处理器为我们自定义的

@Bean

public RestTemplate facePlusRestTemplate() {

HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();

requestFactory.setConnectTimeout(300000);

requestFactory.setReadTimeout(300000);

RestTemplate restTemplate = new RestTemplate(requestFactory);

restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));

restTemplate.getMessageConverters().add(new FormHttpMessageConverter());

restTemplate.setErrorHandler(new FacePlusThrowErrorHandler());

return restTemplate;

}

然后当我们使用restTemplate 时,设置restTemplate bean 名为注入时起的名字

@Resource(name = "facePlusRestTemplate")

private RestTemplate restTemplate;

最后从返回的ResponseEntity 中取body 属性,就可以取得服务端返回的消息体了

自定义RestTemplate的ResponseErrorHandler

Spring框架中的RestTemplate处理ClientHttpResponse的方式

直接看RestTemplate的源码

这里主要判断了是ClientError还是ServerError,即4xx或者是5xx。

如若是这两类状态码,会执行handleError()抛出异常

并不想让它抛异常

在一些业务场景下,或许我们并不想让它抛异常(即便我们可以捕获异常,额外做处理),那么就需要我们ResponseErrorHandler,并且重新定义一个RestTemplate对象使用该ErrorHandler。(简单实现如下)

@Configuration

public class CustomResponseErrorHandler implements ResponseErrorHandler {

@Override

public boolean hasError(ClientHttpResponse clientHttpResponse) throws IOException {

return false;

}

@Override

public void handleError(ClientHttpResponse clientHttpResponse) throws IOException {

}

@Bean("customRestTemplate")

public RestTemplate customRestTemplate() {

HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();

requestFactory.setConnectTimeout(300000);

requestFactory.setReadTimeout(300000);

RestTemplate restTemplate = new RestTemplate(requestFactory);

restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));

restTemplate.getMessageConverters().add(new FormHttpMessageConverter());

restTemplate.setErrorHandler(new CustomResponseErrorHandler());

return restTemplate;

}

}

还需要加入一个maven依赖(具体原因查看maven依赖图)

org.apache.httpcomponents

httpclient

4.5.5

在spring 中以IOC方式注入

@Resource(name = "customRestTemplate")

private RestTemplate restTemplate;

到这里已经可以正常使用。

无法使用IOC注入的场景下

还是参照CustomResponseErrorHandler中的customRestTemplate()去new对象吧……

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:RestTemplate 401 获取错误信息的处理方案
下一篇:RestTemplate自定义ErrorHandler方式
相关文章

 发表评论

暂时没有评论,来抢沙发吧~