2016-06-29 81 views
31

Di seguito è riportato lo snippet di codice; Fondamentalmente, io sto cercando di propagare l'eccezione quando il codice di errore è diverso da 200.Spring Resttemplate exception handling

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

Tuttavia, nel caso di una risposta 500 dal server sto ottenendo l'eccezione

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] 

Do Ho davvero bisogno di avvolgere il resto del metodo di scambio template in prova? Quale sarebbe allora lo scopo dei codici?

+0

Si prega di condividere il codice di ApplicationException() – Mudassar

+0

Possibile duplicato del [Primavera RestTemplate - Overriding ResponseErrorHandler] (https://stackoverflow.com/questions/23838752/spring-resttemplate-overriding-responseerrorhandler) –

risposta

45

Si desidera creare una classe che implementa ResponseErrorHandler e quindi utilizzare un'istanza di esso per impostare la gestione degli errori del vostro modello di riposo:

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

Inoltre, Spring ha la classe DefaultResponseErrorHandler, che è possibile estendere invece di implementare l'interfaccia, nel caso in cui si desideri sovrascrivere solo il metodo handleError.

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

Date un'occhiata al suo source code per avere un'idea di come Primavera gestisce gli errori HTTP.

15

Si dovrebbe prendere un un'eccezione HttpStatusCodeException:

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

IMO la risposta dovrebbe sempre venire con un codice di stato appropriato, altrimenti qual è lo scopo dei codici. – vaibhav

+3

Non sono sicuro di capire obiezione @vaibhav: la cattura di HttpStatusCodeException non è per un codice errato, ma perché in molti casi viene sempre generata un'eccezione e quindi il tuo if (codice == valore) non può mai essere eseguito. –

+1

Le eccezioni sono molto costose in Java. Va bene per le cause occasionali e inaspettate (da cui il nome), ma per il resto dovresti cercare altre soluzioni. –

0

Se si utilizza il meccanismo di pooling (http client factory) o load balancing (eureka) con il proprio RestTemplate, non si avrà il lusso di creare uno new RestTemplate per classe. Se chiami più di un servizio non puoi utilizzare setErrorHandler perché se fosse usato globalmente per tutte le tue richieste.

In questo caso, la cattura dello HttpStatusCodeException sembra essere l'opzione migliore.

L'unica altra opzione disponibile è definire più istanze RestTemplate utilizzando l'annotazione @Qualifier.

Inoltre, ma questo è il mio gusto personale, mi piace il modo in cui gestisco gli errori rannicchiato saldamente alle mie chiamate.