我正在尝试覆盖ResponseErrorHandler接口,以便在2xx以外的任何响应的情况下能够返回整个请求(状态代码,正文等)。
我注意到,在响应不是2xx的情况下,Spring(RestTemplate)的默认值会返回异常。我不想返回异常,我只想能够返回一个:
new ResponseEntity(HttpStatus.STATUS_CODE)
在完成一些教程之后,我发现了以下代码:
@Component
public class LoginErrorHandler
implements ResponseErrorHandler {
@Override
public boolean hasError(ClientHttpResponse httpResponse)
throws IOException {
return (
httpResponse.getStatusCode().series() == CLIENT_ERROR
|| httpResponse.getStatusCode().series() == SERVER_ERROR);
}
@Override
public void handleError(ClientHttpResponse httpResponse)
throws IOException {
if (httpResponse.getStatusCode()
.series() == SERVER_ERROR) {
// handle SERVER_ERROR
} else if (httpResponse.getStatusCode()
.series() == CLIENT_ERROR) {
// handle CLIENT_ERROR
}
}
但是我还不了解如何在不更改方法return的情况下返回ResponseEntity(我无法通过实现方法来实现)。
实施:
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);
RestTemplate restTemplate = new RestTemplate();
restTemplate.setErrorHandler(new LoginErrorHandler());
return restTemplate.postForEntity(url, request, String.class);
答案 0 :(得分:1)
您可以使用Spring的ControllerAdvice
和ExceptionHandler
批注通过应用程序处理异常。如果您的请求中遇到任何异常,则以下代码将返回500个http状态代码。您可以添加其他Exception类或自己的自定义类来处理特定情况,并将特定状态代码返回给客户端。
修改
处理每个代码不是一个好主意。相反,您可以将它们包装在您的自定义异常中,并向客户服务提供正确的消息。您仍然可以尝试以下类似方法。
@Component
@ControllerAdvice
public class MyExceptionHandler {
@ExceptionHandler(HttpClientErrorException.BadRequest.class)
@ResponseStatus(code=HttpStatus.BAD_REQUEST, reason="Bad Request", value=HttpStatus.BAD_REQUEST)
public void handleBadRequest(HttpClientErrorException.BadRequest e) {
//handle bad request exception
}
@ExceptionHandler(HttpClientErrorException.NotFound.class)
@ResponseStatus(code=HttpStatus.NOT_FOUND, reason="Not Found", value=HttpStatus.NOT_FOUND)
public void handleNotFound(HttpClientErrorException.NotFound e) {
//handle Not Found
}
@ExceptionHandler(HttpServerErrorException.InternalServerError.class)
@ResponseStatus(code=HttpStatus.INTERNAL_SERVER_ERROR, reason="Internal Server Error", value=HttpStatus.INTERNAL_SERVER_ERROR)
public void handleInternalServerError(HttpServerErrorException.InternalServerError e) {
//handle internal server error
}
//more methods for each code.
}
然后按以下方式处理其余模板中的代码。在这里,您将无法将响应的正文返回给客户端。
@Component
public class LoginErrorHandler
implements ResponseErrorHandler {
@Override
public boolean hasError(ClientHttpResponse httpResponse)
throws IOException {
return (httpResponse.getStatusCode() != HttpStatus.OK);
}
@Override
public void handleError(ClientHttpResponse httpResponse)
throws IOException {
if (httpResponse.getRawStatusCode() >=400 && httpResponse.getRawStatusCode()<500 ) {
throw HttpClientErrorException.create(httpResponse.getStatusCode(), httpResponse.getStatusText(), httpResponse.getHeaders(), null, null);
}else if(httpResponse.getRawStatusCode() >=500){
throw HttpServerErrorException.create(httpResponse.getStatusCode(), httpResponse.getStatusText(), httpResponse.getHeaders(), null, null);
}else {
//throw some other exceptions for other codes and catch them in controller advice.
}
}
}
答案 1 :(得分:1)
您可以这样做:
@Component
@ControllerAdvice
public class LoginErrorHandler{
@ExceptionHandler(HttpClientErrorException.class)
@ResponseBody
public void handleError(HttpClientErrorException e, HttpServletResponse response) throws IOException {
response.sendError(e.getRawStatusCode(), e.getStatusText());
}
}
这将泛化应删除异常的所有状态代码,并且该代码将在正文中返回。
答案 2 :(得分:0)
Spring框架提供了两个广泛使用且非常方便的异常处理程序,用于在Spring Boot应用程序中进行集中式异常管理。
ResponseEntityExceptionHandler :端点方法抛出的异常(用@RequestMapping
注释的方法)
一个方便的基类,用于希望通过
@ControllerAdvice
方法在所有@RequestMapping
方法之间提供集中式异常处理的@ExceptionHandler
类。
ResponseErrorHandler: Spring提供了一个钩子“ ResponseErrorHandler”,可以将其实现为处理外部服务引发的异常。
RestTemplate
用于确定特定响应是否有错误的策略接口。
使用“ ResponseErrorHandler”有两个步骤:
第1步:通过实现ResponseErrorHandler创建自定义错误处理程序类,并实现其方法hasError和handleError
第2步:使用RestTemplateBuilder将自定义错误处理程序设置为RestTemplate,如下面的代码片段所示: 默认情况下,RestTemplate中的errorHandler指向DefaultResponseErrorHandler。