2017-09-22 6 views
0

J'ai un webservice qui obtient des données d'un autre service web et retourne au navigateur.Comment gérer HttpClientException correctement

  1. Je veux cacher les erreurs des clients internes
  2. voulez jeter 404, 400 etc qui sont renvoyés par le webservice dans la méthode ci-dessous.

Comment résoudre ce problème d'une manière ordonnée?

L'option 1 ou l'option 2 est-elle propre?

Option 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(); 
    } 

(ou)

Option 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

Quel est le problème avec le code ci-dessus? Vous utilisez le code d'état de l'exception interne et le placez dans une nouvelle exception, en masquant l'exception interne. – f1sh

+0

Option2 est moche ... Option1 est beaucoup mieux. Mais je vous suggère de séparer le gestionnaire d'erreurs. Créer un intercepteur qui implémente "ResponseErrorHandler" fourni par le printemps là vous pouvez gérer tous les messages d'erreur afin que votre code sera beaucoup plus propre et vous n'avez pas besoin d'utiliser essayer, attraper le bloc – VelNaga

+0

pouvez-vous me montrer un exemple approprié? Merci. – Minisha

Répondre

0

J'ai écrit un échantillon ResponseErrorHandler pour vous,

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); 
    } 
} 
} 

Note: Cette situation est commune ResponseEr rorHandler pour votre restTemplate et il va attraper toutes les exceptions levées par restTemplate vous n'avez pas besoin d'essayer, catch block dans chaque méthode et vous n'avez pas besoin d'attraper "HttpStatusCodeException" ou toute autre exception.

Veuillez utiliser le code ci-dessous pour enregistrer ce ErrorHandler.

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

Vous pouvez également trouver des exemples here.

Vous pouvez factoriser votre classe client comme celui-ci,

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(); 
} 

Donc, votre méthode ne cherchez pas beau maintenant? Suggestions bienvenues.

+0

Pouvez-vous supprimer le vote pour cette question? Je suppose que la question est tout à fait raisonnable. Et oui au début, je n'étais pas très clair sur ce que je cherchais. Désolé – Minisha

+0

@MinishaMurugan Je n'ai pas critiqué la question, c'est quelqu'un qui l'a fait. Mais peu importe, vous avez la bonne réponse ... donc pas de soucis – VelNaga