首页 > 解决方案 > 实现 ResponseErrorHandler 接口

问题描述

我正在尝试覆盖 ResponseErrorHandler 接口,以便能够在除 2xx 之外的任何响应的情况下返回整个请求(状态代码、正文等)。

我注意到 Spring (RestTemplate) 默认在响应不是 2xx 的情况下返回异常。我不想返回异常,我只想能够返回:

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
        }
    }

参考

但是我不明白如何在不更改方法返回的情况下返回一个 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);

标签: javaspringspring-bootrequest

解决方案


您可以使用 SpringControllerAdviceExceptionHandler注释通过您的应用程序处理异常。如果您的请求中遇到任何异常,下面的代码将返回 500 http 状态代码。您可以添加其他异常类或您自己的自定义类来处理特定情况并将特定状态代码返回给客户端。

编辑

处理每个代码都不是一个好主意。相反,您可以将它们包装在您的自定义异常中,并向您的客户服务提供适当的消息。您仍然可以尝试以下方法。

@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.
        }
    }
}

推荐阅读