当前位置: 首页 > 知识库问答 >
问题:

Rest模板自定义异常处理

卜勇
2023-03-14

我正在使用来自外部API的一些RESTendpoint,为此我正在使用REST模板接口。当我从这些调用中收到某些HTTP状态代码时,我希望能够抛出自定义应用程序异常。为了实现它,我正在实现ResponseErrorHandler接口,如下所示:

public class MyCustomResponseErrorHandler implements ResponseErrorHandler {

    private ResponseErrorHandler myErrorHandler = new DefaultResponseErrorHandler();

    public boolean hasError(ClientHttpResponse response) throws IOException {
        return myErrorHandler.hasError(response);
    }

    public void handleError(ClientHttpResponse response) throws IOException {
        String body = IOUtils.toString(response.getBody());
        MyCustomException exception = new MyCustomException(response.getStatusCode(), body, body);
        throw exception;
    }

}

public class MyCustomException extends IOException {

    private HttpStatus statusCode;

    private String body;

    public MyCustomException(String msg) {
        super(msg);
        // TODO Auto-generated constructor stub
    }

    public MyCustomException(HttpStatus statusCode, String body, String msg) {
        super(msg);
        this.statusCode = statusCode;
        this.body = body;
    }

    public HttpStatus getStatusCode() {
        return statusCode;
    }

    public void setStatusCode(HttpStatus statusCode) {
        this.statusCode = statusCode;
    }

    public String getBody() {
        return body;
    }

    public void setBody(String body) {
        this.body = body;
    }

}

最后,这是客户端代码(无关代码省略):

public LoginResponse doLogin(String email, String password) {
    HttpEntity<?> requestEntity = new HttpEntity<Object>(crateBasicAuthHeaders(email,password));
    try{
        ResponseEntity<LoginResponse> responseEntity = restTemplate.exchange(myBaseURL + "/user/account/" + email, HttpMethod.GET, requestEntity, LoginResponse.class);
        return responseEntity.getBody();
    } catch (Exception e) {
        //Custom error handler in action, here we're supposed to receive a MyCustomException
        if (e instanceof MyCustomException){
            MyCustomException exception = (MyCustomException) e;
            logger.info("An error occurred while calling api/user/account API endpoint: " + e.getMessage());
        } else {
             logger.info("An error occurred while trying to parse Login Response JSON object");
        }
    }
    return null;
}

我的应用程序上下文:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:spring="http://camel.apache.org/schema/spring"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">

    <!-- Rest template (used in bridge communication) -->
    <bean id="restTemplate" class="org.springframework.web.client.RestTemplate">
        <property name="errorHandler" ref="myCustomResponseErrorHandler"></property>
    </bean>

    <!-- Bridge service -->
    <bean id="myBridgeService" class="a.b.c.d.service.impl.MyBridgeServiceImpl"/>

    <!-- Bridge error handler -->
    <bean id="myCustomResponseErrorHandler" class="a.b.c.d.service.handlers.MyCustomResponseErrorHandler"/>

</beans>

我怀疑我没有正确理解此自定义错误处理的行为。每个rest模板方法都可能抛出一个RestClientException,它遵循异常层次结构,是RuntimeException的子类,而不是IOException,它是在自定义响应错误处理程序中抛出的,即:我无法在rest模板方法调用中捕获自定义异常。

关于我如何捕捉这些异常的任何线索?SpringRestTemplate调用带有错误的webservice和分析状态代码是高度相关的,但从我的角度来看,遇到了相同的问题,尽管它是作为一种解决方案提出的。

[1]:

共有2个答案

胥博文
2023-03-14

如果使用springmvc,则可以使用annotation@ControllerAdvice创建控制器。在控制器中写入:

@ExceptionHandler(HttpClientErrorException.class)
public String handleXXException(HttpClientErrorException e) {
    log.error("log HttpClientErrorException: ", e);
    return "HttpClientErrorException_message";
}

@ExceptionHandler(HttpServerErrorException.class)
public String handleXXException(HttpServerErrorException e) {
    log.error("log HttpServerErrorException: ", e);
    return "HttpServerErrorException_message";
}
...
// catch unknown error
@ExceptionHandler(Exception.class)
public String handleException(Exception e) {
    log.error("log unknown error", e);
    return "unknown_error_message";
}

DefaultResponseErrorHandler抛出这两种异常:

@Override
public void handleError(ClientHttpResponse response) throws IOException {
    HttpStatus statusCode = getHttpStatusCode(response);
    switch (statusCode.series()) {
        case 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 + "]");
    }
}

您可以使用:e.get响应身体AsString();e.getStatusCode();blabla在异常发生时获取响应消息。

孔瑾瑜
2023-03-14

您已经使您的自定义异常IOExc0019扩展

public class MyCustomException extends IOException {

ResponseErrorHandler#handleError()方法从RestTemplate#HandlerResponseError(..)调用 RestTemplate#doExecute(..)调用 。此根调用被包装在一个try catch块中,该块捕获IOException,并将其重新包装在ResourceAccessException中,后者是一个RestClientException

一种可能性是捕获RestClientExcsion并获取其原因

另一种可能是使自定义的异常成为运行时异常的子类型。

 类似资料:
  • 我想为REST API做自定义异常处理。 这是我掌握的密码。 如何使自定义错误类捕获并显示自定义错误? 谢谢

  • 我使用的是Nifi 0.4.1版本。我写自定义代码转换CSV到avro格式。我已经创建了类文件,并能够生成nar文件。将nar文件放置在lib目录中,并重新启动nifi服务器。 任何帮助都很感激.. 谢谢,

  • 我的要求是,如果post请求的JSON无效,我将需要发送400个HTTP响应代码,如果任何字段不可解析,返回状态代码将为422。例如,post请求可以是: Dto类提供如下:, 这是发出POST请求的控制器, 如果“金额”是,比如说,“sfdfd”,这不是大小数,我们应该提供422。但如果“金额”为“-12.3343”,则这是约束验证错误,但数据有效且可分析。所以我们不能拥有422。 这是我的异常

  • 我创建了一个自定义endpoint来利用某些数据的异步处理。现在,我想将处理结果传送到另一条路由,以便将结果保存在数据库中,但我不知道如何访问异步处理器中的producer模板。

  • 我已经为我的spring boot应用程序创建了一个自定义REST控制器异常处理程序。。。 ... 我处理验证、业务(由于违反业务规则而导致的异常)和技术(与数据库相关、无效的请求参数等)异常。 异常类有两个参数:errorCode(唯一枚举)和消息(异常详细信息)。 正如您从示例中看到的,对于所有情况,我都会返回BAD_REQUEST(400)状态,这不是最佳做法。 我想知道基于异常类别处理HT

  • 我在看一本书《Spring在行动》第5版,但我认为这是一个错误。 这是这本书的GitHub。我已经到了第3章tacos-jdbc代码源码 submit my order时突然出现错误: OrderController: 和OrderForm: