实现ResponseErrorHandler接口

时间:2019-06-18 11:25:19

标签: java spring spring-boot request

我正在尝试覆盖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
        }
    }

Reference

但是我还不了解如何在不更改方法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);

3 个答案:

答案 0 :(得分:1)

您可以使用Spring的ControllerAdviceExceptionHandler批注通过应用程序处理异常。如果您的请求中遇到任何异常,则以下代码将返回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类。

enter image description here

ResponseErrorHandler: Spring提供了一个钩子“ ResponseErrorHandler”,可以将其实现为处理外部服务引发的异常。

  

RestTemplate用于确定特定响应是否有错误的策略接口。

使用“ ResponseErrorHandler”有两个步骤:

第1步:通过实现ResponseErrorHandler创建自定义错误处理程序类,并实现其方法hasError和handleError

enter image description here

第2步:使用RestTemplateBuilder将自定义错误处理程序设置为RestTemplate,如下面的代码片段所示: enter image description here 默认情况下,RestTemplate中的errorHandler指向DefaultResponseErrorHandler。

Source