2017-09-22 2 views
0

다른 웹 서비스에서 데이터를 가져 와서 브라우저로 돌아가는 webservice가 있습니다.HttpClientException을 올바르게 처리하는 방법

  1. 나는, 400 등 은 아래의 방법으로 웹 서비스에서 반환되는을
  2. (404)을 던져 원 내부 클라이언트 오류를 ​​숨기려고합니다.

깔끔한 방법으로이 문제를 해결하는 방법은 무엇입니까?

옵션 1 또는 옵션 2는 깨끗한 방법입니까?

옵션 1

public <T> Optional<T> get(String url, Class<T> responseType) { 
     String fullUrl = url; 
     LOG.info("Retrieving data from url: "+fullUrl); 
     try { 
      HttpHeaders headers = new HttpHeaders(); 
      headers.setAccept(ImmutableList.of(MediaType.APPLICATION_JSON)); 
      headers.add("Authorization", "Basic " + httpAuthCredentials); 

      HttpEntity<String> request = new HttpEntity<>(headers); 
      ResponseEntity<T> exchange = restTemplate.exchange(fullUrl, HttpMethod.GET, request, responseType); 
      if(exchange !=null) 
       return Optional.of(exchange.getBody()); 
     } catch (HttpClientErrorException e) { 
      LOG.error("Client Exception ", e); 
      throw new HttpClientError("Client Exception: "+e.getStatusCode()); 
     } 
     return Optional.empty(); 
    } 

(또는)

내가 당신을 위해 샘플 ResponseErrorHandler를 작성했습니다 2

public <T> Optional<T> get(String url, Class<T> responseType) { 
     String fullUrl = url; 
     LOG.info("Retrieving data from url: "+fullUrl); 
     try { 
      HttpHeaders headers = new HttpHeaders(); 
      headers.setAccept(ImmutableList.of(MediaType.APPLICATION_JSON)); 
      headers.add("Authorization", "Basic " + httpAuthCredentials); 

      HttpEntity<String> request = new HttpEntity<>(headers); 
      ResponseEntity<T> exchange = restTemplate.exchange(fullUrl, HttpMethod.GET, request, responseType); 
      if(exchange !=null) 
       return Optional.of(exchange.getBody()); 
      throw new RestClientResponseException("", 400, "", null, null, null); 
     } catch (HttpStatusCodeException e) { 
      LOG.error("HttpStatusCodeException ", e); 
      throw new RestClientResponseException(e.getMessage(), e.getStatusCode().value(), e.getStatusText(), e.getResponseHeaders(), e.getResponseBodyAsByteArray(), Charset.defaultCharset()); 
     } 
     return Optional.empty(); 
    } 
+0

위 코드의 문제점은 무엇입니까? 내부 예외의 상태 코드를 사용하여 내부 예외를 숨기는 새로운 예외에 넣습니다. – f1sh

+0

Option2가보기 흉한 ... Option1이 훨씬 좋습니다. 하지만 난 당신이 오류 처리기를 분리하는 것이 좋습니다 것입니다. Spring에서 제공하는 "ResponseErrorHandler"를 구현하는 인터셉터를 생성하십시오. 모든 오류 메시지를 처리하여 코드가 훨씬 깨끗해 지도록 시도하십시오. catch 블록을 사용하지 않아도됩니다. – VelNaga

+0

적절한 예를 들어 주시겠습니까? 감사. – Minisha

답변

0

옵션,

public class RestTemplateClientErrorHandler implements ResponseErrorHandler { 

private static final Logger logger = LoggerFactory.getLogger(RestTemplateClientErrorHandler.class); 

@Override 
public boolean hasError(ClientHttpResponse clientHttpResponse) throws IOException { 
    return RestUtil.isError(clientHttpResponse.getStatusCode()); 
} 

@Override 
public void handleError(ClientHttpResponse clientHttpResponse) throws IOException { 
    String responseBody = ""; 
    if(clientHttpResponse != null && clientHttpResponse.getBody() != null){ 
     responseBody = IOUtils.toString(clientHttpResponse.getBody()); 
    } 
    switch(clientHttpResponse.getRawStatusCode()){ 
     case 404: 
      logger.error("Entity not found. Message: {}. Status: {} ",responseBody,clientHttpResponse.getStatusCode()); 
      throw new RestClientResponseException(responseBody); 
     case 400: 
      logger.error("Bad request for entity. Message: {}. Status: {}",responseBody, clientHttpResponse.getStatusCode()); 
      throw new RestClientResponseException(StringUtils.EMPTY, 400,StringUtils.EMPTY, StringUtils.EMPTY, StringUtils.EMPTY, StringUtils.EMPTY); 
     default: 
      logger.error("Unexpected HTTP status: {} received when trying to delete entity in device repository.", clientHttpResponse.getStatusCode()); 
      throw new RestClientResponseException(responseBody); 
    } 

} 

public static class RestUtil { 

    private RestUtil() { 
     throw new IllegalAccessError("Utility class"); 
    } 

    public static boolean isError(HttpStatus status) { 
     HttpStatus.Series series = status.series(); 
     return HttpStatus.Series.CLIENT_ERROR.equals(series) 
       || HttpStatus.Series.SERVER_ERROR.equals(series); 
    } 
} 
} 

참고 :이 일반적이다 ResponseEr 당신의 restTemplate에 대한 rorHandler 그리고 restTemplate에 의해 던져진 모든 예외를 잡을 것입니다. 당신이 시도 할 필요가 없으며, 각 메소드에서 블록을 잡을 것이고 "HttpStatusCodeException"또는 다른 예외를 잡을 필요가 없습니다.

아래의 코드를 사용하여이 ErrorHandler를 등록하십시오.

RestTemplate restTemplate = new RestTemplate(); 
restTemplate.setErrorHandler(new RestTemplateClientErrorHandler()); 

here도 찾을 수 있습니다.

당신은이 같은 클라이언트 클래스는,

public <T> Optional<T> get(String url, Class<T> responseType) { 
    String fullUrl = url; 
    LOG.info("Retrieving data from url: "+fullUrl); 
     HttpHeaders headers = new HttpHeaders(); 

     headers.setAccept(ImmutableList.of(MediaType.APPLICATION_JSON)); 
     headers.add("Authorization", "Basic " + httpAuthCredentials); 

     HttpEntity<String> request = new HttpEntity<>(headers); 
     ResponseEntity<T> exchange = restTemplate.exchange(fullUrl, HttpMethod.GET, request, responseType); 
     if(exchange !=null) 
      return Optional.of(exchange.getBody()); 
    return Optional.empty(); 
} 

그래서 당신의 방법은 지금 아름다운보고 있지 리팩토링 할 수 있습니까? 제안을 환영합니다.

+0

이 질문에 대한 투표를 취소 할 수 있습니까? 나는 그 질문이 꽤 합리적이라고 생각한다. 그리고 처음에는 네가 찾고있는 것이 분명하지 않았다. 죄송합니다 – Minisha

+0

@MinishaMurugan 나는 그것을 한 사람의 질문을 downvote하지 않았다. 하지만 그 말이 맞다는 것은 중요하지 않습니다 ... 그래서 아무 걱정도 pannuga를 즐기지 않습니다. – VelNaga