복붙노트

[SPRING] 나머지 템플릿 사용자 정의 예외 처리

SPRING

나머지 템플릿 사용자 정의 예외 처리

외부 API에서 일부 REST 끝점을 사용하고 있으며 나머지 템플릿 인터페이스를이 용도로 사용하고 있습니다. 이러한 호출에서 특정 HTTP 상태 코드를 수신 할 때 사용자 지정 응용 프로그램 예외를 throw 할 수 싶습니다. 이를 달성하기 위해 다음과 같이 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>

나는이 사용자 정의 오류 처리의 동작을 올바르게 이해하지 못하고 있다고 생각합니다. 모든 나머지 단일 템플릿 메서드는 예외 계층에 이어 RestClientException을 던질 수 있습니다.이 클래스는 사용자 지정 응답 오류 처리기에서 throw되는 IOException이 아닌 RuntimeException의 하위 클래스입니다. 나머지 템플릿 메서드에서 사용자 지정 예외를 catch 할 수 없습니다. 전화.

이러한 예외를 잡을 수있는 방법에 대한 단서가 있습니까? Spring RestTemplate은 오류가있는 webservice를 호출하고 상태 코드를 분석하는 것은 매우 관련이 있지만 해결책으로 제안되었지만 내 관점에서는 동일한 문제를 경험합니다.

[1]:

해결법

  1. ==============================

    1.사용자 정의 예외를 IOException에서 확장했습니다.

    사용자 정의 예외를 IOException에서 확장했습니다.

    public class MyCustomException extends IOException {
    

    ResponseErrorHandler # handleError () 메서드는 RestTemplate # doExecute (..)에 의해 호출되는 RestTemplate # handleResponseError (..)에서 호출됩니다. 이 루트 호출은 IOException을 포착하고 RestClientException 인 ResourceAccessException에 랩핑 된 try-catch 블록에 랩핑됩니다.

    한 가지 가능성은 RestClientException을 포착하고 그 원인을 얻는 것입니다.

    또 다른 가능성은 사용자 정의 Exception을 RuntimeException의 하위 유형으로 만드는 것입니다.

  2. ==============================

    2.springmvc를 사용하는 경우 @ControllerAdvice 주석을 사용하여 컨트롤러를 만들 수 있습니다. 컨트롤러 쓰기 :

    springmvc를 사용하는 경우 @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는 다음 두 가지 예외를 throw합니다.

    @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.getResponseBodyAsString (); e.getStatusCode (); blabla 예외가 발생할 때 응답 메시지를 가져옵니다.

  3. from https://stackoverflow.com/questions/21429899/rest-template-custom-exception-handling by cc-by-sa and MIT license