Spring RestTemplate - 覆盖 ResponseErrorHandler

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23838752/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 06:45:12  来源:igfitidea点击:

Spring RestTemplate - Overriding ResponseErrorHandler

springrestspring-mvcresttemplate

提问by user3670450

I am calling a ReSTservice through RestTemplateand trying to override ResponseErrorHandlerin Spring 3.2to handle custom error codes.

我打电话一个ReST通过服务RestTemplate,并试图覆盖ResponseErrorHandlerSpring 3.2处理自定义错误代码。

CustomResponseErrroHandler

自定义响应错误处理程序

public class MyResponseErrorHandler implements ResponseErrorHandler {

    @Override
    public boolean hasError(ClientHttpResponse response) throws IOException {
        boolean hasError = false;
        int rawStatusCode = response.getRawStatusCode();
        if (rawStatusCode != 200){
            hasError = true;
        }
        return hasError;
     }

    @Override
    public void handleError(ClientHttpResponse response) throws IOException {
        //String body = IOUtils.toString(response.getBody());
        throw new CustomServiceException(response.getRawStatusCode() , "custom Error");
   }
}

Springframework invokes hasErrormethod but not handleError, so I couldn't throw my custom exception. After delving into SpringRestTemplatesource code, I realized that the code in handleResponseErrormethod is causing the issue - It is looking for response.getStatusCodeor response.getStatusTextand throwing exception (as statusCode/statusText is null when Restservice throws exception) and it never calls either custom implemented or default handleErrormethod in the next line.

Spring框架调用hasError方法而不是handleError,所以我不能抛出我的自定义异常。在深入研究SpringRestTemplate源代码后,我意识到handleResponseError方法中的代码导致了问题 - 它正在寻找response.getStatusCodeorresponse.getStatusText并抛出异常(因为 statusCode/statusText 在Rest服务抛出异常时为 null )并且它从不调用自定义实现或默认handleError方法下一行。

SpringRestTemplatesource code for handleResponsemethod:

SpringRestTemplatehandleResponse方法的源代码:

private void handleResponseError(HttpMethod method, URI url, ClientHttpResponse response) throws IOException {
    if (logger.isWarnEnabled()) {
        try {
            logger.warn(method.name() + " request for \"" + url + "\" resulted in " +
response.getStatusCode() + " (" + response.getStatusText() + "); invoking error handler");
        }
        catch (IOException e) {
            // ignore
        }
    }
    getErrorHandler().handleError(response);
}

FYI, while service throws exception, I can read rawstatuscode but not statuscode from response

仅供参考,当服务抛出异常时,我可以从响应中读取 rawstatuscode 但不能读取 statuscode

How to bypass this framework code and make call my custom handler? Thanks for your help in advance.

如何绕过此框架代码并调用我的自定义处理程序?提前感谢您的帮助。

回答by Abhijeet

Following link has useful information about Exception Flow for Spring ResponseErrorHandler.

以下链接包含有关Spring ResponseErrorHandler 异常流的有用信息。

Adding code here, just in-case the blog is down:

在此处添加代码,以防万一博客关闭:

Code for ErrorHandler:

ErrorHandler 的代码:

public class MyResponseErrorHandler implements ResponseErrorHandler {

    private static final Log logger = LogFactory.getLog(MyResponseErrorHandler.class);

    @Override
    public void handleError(ClientHttpResponse clienthttpresponse) throws IOException {

        if (clienthttpresponse.getStatusCode() == HttpStatus.FORBIDDEN) {
            logger.debug(HttpStatus.FORBIDDEN + " response. Throwing authentication exception");
            throw new AuthenticationException();
        }
    }

    @Override
    public boolean hasError(ClientHttpResponse clienthttpresponse) throws IOException {

        if (clienthttpresponse.getStatusCode() != HttpStatus.OK) {
            logger.debug("Status code: " + clienthttpresponse.getStatusCode());
            logger.debug("Response" + clienthttpresponse.getStatusText());
            logger.debug(clienthttpresponse.getBody());

            if (clienthttpresponse.getStatusCode() == HttpStatus.FORBIDDEN) {
                logger.debug("Call returned a error 403 forbidden resposne ");
                return true;
            }
        }
        return false;
    }
}

Code for using it in RestTemplate:

在 RestTemplate 中使用它的代码:

RestTemplate restclient = new RestTemplate();
restclient.setErrorHandler(new MyResponseErrorHandler());
ResponseEntity<String> responseEntity = clientRestTemplate.exchange(
                    URI,
                    HttpMethod.GET,
                    requestEntity,
                    String.class);
                response = responseEntity.getBody();

回答by nilesh

I don't see your RestTemplatecode, but I assume you to set your ResponseErrorHandlerfor RestTemplateto use like:

我没有看到您的RestTemplate代码,但我假设您将ResponseErrorHandlerfor设置为RestTemplate使用如下:

RestTemplate restClient = new RestTemplate();
restClient.setErrorHandler(new MyResponseErrorHandler());

The exception is indeed thrown in handleErrormethod. You can find how to throw CustomExceptionusing CustomResponseHandlerfrom one of my previous answers.

异常确实是在handleError方法中抛出的。你可以找到如何抛出CustomException使用CustomResponseHandler我以前的答案之一