복붙노트

[SPRING] Spring Resttemplate 예외 처리

SPRING

Spring Resttemplate 예외 처리

아래는 코드 스 니펫입니다. 기본적으로 오류 코드가 200이 아닌 다른 예외를 전파하려고합니다.

ResponseEntity<Object> response = restTemplate.exchange(url.toString().replace("{version}", version),
                    HttpMethod.POST, entity, Object.class);
            if(response.getStatusCode().value()!= 200){
                logger.debug("Encountered Error while Calling API");
                throw new ApplicationException();
            }

그러나 서버에서 응답이 500 인 경우 예외가 발생합니다.

org.springframework.web.client.HttpServerErrorException: 500 Internal Server Error
    at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:94) ~[spring-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]

정말 나머지 템플릿 교환 방법을 시도해야합니까? 그러면 코드의 목적은 무엇입니까?

해결법

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

    1.ResponseErrorHandler를 구현 한 클래스를 만든 다음이 템플릿의 인스턴스를 사용하여 나머지 템플릿의 오류 처리를 설정하려고합니다.

    ResponseErrorHandler를 구현 한 클래스를 만든 다음이 템플릿의 인스턴스를 사용하여 나머지 템플릿의 오류 처리를 설정하려고합니다.

    public class MyErrorHandler implements ResponseErrorHandler {
      @Override
      public void handleError(ClientHttpResponse response) throws IOException {
        // your error handling here
      }
    
      @Override
      public boolean hasError(ClientHttpResponse response) throws IOException {
         ...
      }
    }
    
    [...]
    
    public static void main(String args[]) {
      RestTemplate restTemplate = new RestTemplate();
      restTemplate.setErrorHandler(new MyErrorHandler());
    }
    

    또한, Spring은 DefaultResponseErrorHandler 클래스를 가지고 있는데, handleError 메소드를 오버라이드하고 싶을 뿐이므로 인터페이스를 구현하는 대신 확장 할 수있다.

    public class MyErrorHandler extends DefaultResponseErrorHandler {
      @Override
      public void handleError(ClientHttpResponse response) throws IOException {
        // your error handling here
      }
    }
    

    Spring이 HTTP 오류를 처리하는 방법에 대한 아이디어를 얻으려면 소스 코드를 살펴보십시오.

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

    2.HttpStatusCodeException 예외를 catch해야합니다.

    HttpStatusCodeException 예외를 catch해야합니다.

    try {
        restTemplate.exchange(...);
    } catch (HttpStatusCodeException exception) {
        int statusCode = exception.getStatusCode().value();
        ...
    }
    
  3. ==============================

    3.Spring은 HTTP 오류 코드를 영리하게 예외로 취급하며 예외 처리 코드에 오류를 처리 할 컨텍스트가 있다고 가정합니다. 예상대로 기능을 수행하려면 다음과 같이하십시오.

    Spring은 HTTP 오류 코드를 영리하게 예외로 취급하며 예외 처리 코드에 오류를 처리 할 컨텍스트가 있다고 가정합니다. 예상대로 기능을 수행하려면 다음과 같이하십시오.

        try {
            return restTemplate.exchange(url, httpMethod, httpEntity, String.class);
        } catch(HttpStatusCodeException e) {
            return ResponseEntity.status(e.getRawStatusCode()).headers(e.getResponseHeaders())
                    .body(e.getResponseBodyAsString());
        }
    

    그러면 응답에서 예상되는 모든 결과가 반환됩니다.

  4. ==============================

    4.또 다른 해결책은이 게시물의 마지막 부분에 "enlian"이 묘사 한 것입니다. http://springinpractice.com/2013/10/07/handling-json-error-object-responses-with-springs-resttemplate

    또 다른 해결책은이 게시물의 마지막 부분에 "enlian"이 묘사 한 것입니다. http://springinpractice.com/2013/10/07/handling-json-error-object-responses-with-springs-resttemplate

    try{
         restTemplate.exchange(...)
    } catch(HttpStatusCodeException e){
         String errorpayload = e.getResponseBodyAsString();
         //do whatever you want
    } catch(RestClientException e){
         //no response payload, tell the user sth else 
    }
    
  5. ==============================

    5.RestTemplate과 함께 풀링 (http 클라이언트 팩토리) 또는로드 밸런싱 (유레카) 메커니즘을 사용하면 클래스 당 새 RestTemplate을 만들지 않아도됩니다. 둘 이상의 서비스를 호출하는 경우 setErrorHandler를 사용할 수 없습니다. 왜냐하면 if가 모든 요청에 ​​대해 전역 적으로 사용되기 때문입니다.

    RestTemplate과 함께 풀링 (http 클라이언트 팩토리) 또는로드 밸런싱 (유레카) 메커니즘을 사용하면 클래스 당 새 RestTemplate을 만들지 않아도됩니다. 둘 이상의 서비스를 호출하는 경우 setErrorHandler를 사용할 수 없습니다. 왜냐하면 if가 모든 요청에 ​​대해 전역 적으로 사용되기 때문입니다.

    이 경우 HttpStatusCodeException을 잡는 것이 더 나은 옵션 인 것 같습니다.

    다른 옵션은 @Qualifier 주석을 사용하여 여러 RestTemplate 인스턴스를 정의하는 것뿐입니다.

    또한 -하지만 이것은 내 자신의 취향입니다 - 저는 제 오류 처리가 제 전화에 단단히 매달려있는 것을 좋아합니다.

  6. ==============================

    6.교환 코드는 다음과 같습니다.

    교환 코드는 다음과 같습니다.

    public <T> ResponseEntity<T> exchange(String url, HttpMethod method,
                HttpEntity<?> requestEntity, Class<T> responseType, Object... uriVariables) throws RestClientException
    

    예외 RestClientException에는 HttpClientErrorException 및 HttpStatusCodeException 예외가 있습니다.

    따라서 RestTemplete에서 HttpClientErrorException 및 HttpStatusCodeException 예외가 발생할 수 있습니다. 예외 객체에서는 다음과 같은 방법으로 정확한 오류 메시지를 얻을 수 있습니다. exception.getResponseBodyAsString ()

    다음은 예제 코드입니다.

    public Object callToRestService(HttpMethod httpMethod, String url, Object requestObject, Class<?> responseObject) {
    
            printLog( "Url : " + url);
            printLog( "callToRestService Request : " + new GsonBuilder().setPrettyPrinting().create().toJson(requestObject));
    
            try {
    
                RestTemplate restTemplate = new RestTemplate();
                restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
                restTemplate.getMessageConverters().add(new StringHttpMessageConverter());
    
    
                HttpHeaders requestHeaders = new HttpHeaders();
                requestHeaders.setContentType(MediaType.APPLICATION_JSON);
    
                HttpEntity<Object> entity = new HttpEntity<>(requestObject, requestHeaders);
    
                long start = System.currentTimeMillis();
    
                ResponseEntity<?> responseEntity = restTemplate.exchange(url, httpMethod, entity, responseObject);
    
                printLog( "callToRestService Status : " + responseEntity.getStatusCodeValue());
    
    
                printLog( "callToRestService Body : " + new GsonBuilder().setPrettyPrinting().create().toJson(responseEntity.getBody()));
    
                long elapsedTime = System.currentTimeMillis() - start;
                printLog( "callToRestService Execution time: " + elapsedTime + " Milliseconds)");
    
                if (responseEntity.getStatusCodeValue() == 200 && responseEntity.getBody() != null) {
                    return responseEntity.getBody();
                }
    
            } catch (HttpClientErrorException exception) {
                printLog( "callToRestService Error :" + exception.getResponseBodyAsString());
                //Handle exception here
            }catch (HttpStatusCodeException exception) {
                printLog( "callToRestService Error :" + exception.getResponseBodyAsString());
                //Handle exception here
            }
            return null;
        }
    

    코드 설명은 다음과 같습니다.

    이 메서드에서는 요청 및 응답 클래스를 전달해야합니다. 이 메소드는 자동으로 응답을 요청 된 객체로 구문 분석합니다.

    우선 당신은 메시지 변환기를 추가해야합니다.

    restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
                restTemplate.getMessageConverters().add(new StringHttpMessageConverter());
    

    그런 다음 requestHeader를 추가해야합니다. 다음은 코드입니다.

    HttpHeaders requestHeaders = new HttpHeaders();
                requestHeaders.setContentType(MediaType.APPLICATION_JSON);
    
                HttpEntity<Object> entity = new HttpEntity<>(requestObject, requestHeaders);
    

    마지막으로 교환 방법을 호출해야합니다.

    ResponseEntity<?> responseEntity = restTemplate.exchange(url, httpMethod, entity, responseObject);
    

    prety 인쇄를 위해 저는 Gson 라이브러리를 사용했습니다.  여기에 gradle입니다 : compile 'com.google.code.gson : gson : 2.4'

    벨로우즈 코드를 호출하여 응답을받을 수 있습니다.

    ResponseObject response=new RestExample().callToRestService(HttpMethod.POST,"URL_HERE",new RequestObject(),ResponseObject.class);
    

    다음은 전체 작업 코드입니다.

    import com.google.gson.GsonBuilder;
    import org.springframework.http.*;
    import org.springframework.http.converter.StringHttpMessageConverter;
    import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
    import org.springframework.web.client.HttpClientErrorException;
    import org.springframework.web.client.HttpStatusCodeException;
    import org.springframework.web.client.RestTemplate;
    
    
    public class RestExample {
    
        public RestExample() {
    
        }
    
        public Object callToRestService(HttpMethod httpMethod, String url, Object requestObject, Class<?> responseObject) {
    
            printLog( "Url : " + url);
            printLog( "callToRestService Request : " + new GsonBuilder().setPrettyPrinting().create().toJson(requestObject));
    
            try {
    
                RestTemplate restTemplate = new RestTemplate();
                restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
                restTemplate.getMessageConverters().add(new StringHttpMessageConverter());
    
    
                HttpHeaders requestHeaders = new HttpHeaders();
                requestHeaders.setContentType(MediaType.APPLICATION_JSON);
    
                HttpEntity<Object> entity = new HttpEntity<>(requestObject, requestHeaders);
    
                long start = System.currentTimeMillis();
    
                ResponseEntity<?> responseEntity = restTemplate.exchange(url, httpMethod, entity, responseObject);
    
                printLog( "callToRestService Status : " + responseEntity.getStatusCodeValue());
    
    
                printLog( "callToRestService Body : " + new GsonBuilder().setPrettyPrinting().create().toJson(responseEntity.getBody()));
    
                long elapsedTime = System.currentTimeMillis() - start;
                printLog( "callToRestService Execution time: " + elapsedTime + " Milliseconds)");
    
                if (responseEntity.getStatusCodeValue() == 200 && responseEntity.getBody() != null) {
                    return responseEntity.getBody();
                }
    
            } catch (HttpClientErrorException exception) {
                printLog( "callToRestService Error :" + exception.getResponseBodyAsString());
                //Handle exception here
            }catch (HttpStatusCodeException exception) {
                printLog( "callToRestService Error :" + exception.getResponseBodyAsString());
                //Handle exception here
            }
            return null;
        }
    
        private void printLog(String message){
            System.out.println(message);
        }
    }
    

    감사 :)

  7. ==============================

    7.다음은 모든 유형의 불량 응답에 대한 응답 본문을 반환하는 HTTPS를 사용하는 POST 메서드입니다.

    다음은 모든 유형의 불량 응답에 대한 응답 본문을 반환하는 HTTPS를 사용하는 POST 메서드입니다.

    public String postHTTPSRequest(String url,String requestJson)
    {
        //SSL Context
        CloseableHttpClient httpClient = HttpClients.custom().setSSLHostnameVerifier(new NoopHostnameVerifier()).build();
        HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
        requestFactory.setHttpClient(httpClient);
        //Initiate REST Template
        RestTemplate restTemplate = new RestTemplate(requestFactory);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        //Send the Request and get the response.
        HttpEntity<String> entity = new HttpEntity<String>(requestJson,headers);
        ResponseEntity<String> response;
        String stringResponse = "";
        try {
            response = restTemplate.postForEntity(url, entity, String.class);
            stringResponse = response.getBody();
        }
        catch (HttpClientErrorException e)
        {
            stringResponse = e.getResponseBodyAsString();
        }
        return stringResponse;
    }
    
  8. from https://stackoverflow.com/questions/38093388/spring-resttemplate-exception-handling by cc-by-sa and MIT license