2016-06-29 40 views
31

Poniżej znajduje się fragment kodu; Zasadniczo, staram się propagować wyjątek, gdy kod błędu jest coś innego niż 200.Obsługa wyjątków Spring Resttemplate

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

Jednak w przypadku 500 odpowiedzi z serwera Dostaję wyjątkiem

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 Naprawdę muszę opakować resztę metody wymiany szablonów w próbie? Jaki byłby cel kodów?

+0

Prosimy udostępnić kod ApplicationException() – Mudassar

+0

Możliwy duplikat [wiosennym RestTemplate - Nadrzędny ResponseErrorHandler] (https://stackoverflow.com/questions/23838752/spring-resttemplate-overriding-responseerrorhandler) –

Odpowiedz

45

Chcesz utworzyć klasę, która implementuje ResponseErrorHandler a następnie użyć instancji nim ustawić obsługę błędów w szablonie rekreacyjne:

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

Ponadto, Spring ma klasę DefaultResponseErrorHandler, którą można rozszerzyć zamiast implementować interfejs, w przypadku, gdy chcesz tylko zastąpić metodę handleError.

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

Spójrz na jego source code mieć wyobrażenie jak Wiosna obsługuje błędów HTTP.

15

Należy złapać HttpStatusCodeException wyjątek:

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

IMO odpowiedź powinna zawsze przyjść z odpowiednim kodem statusu, w przeciwnym razie jaki jest cel kodów. – vaibhav

+3

Nie jestem pewien, aby zrozumieć sprzeciw @vaibhav: przechwytywanie HttpStatusCodeException nie jest dla złego kodu, ale ponieważ w wielu przypadkach wyjątek jest zawsze wyrzucany, a więc twoje if (kod == wartość) nigdy nie może być wykonane. –

+1

Wyjątki są bardzo kosztowne w Javie. Jest OK dla sporadycznych, nieoczekiwanych przyczyn (stąd nazwa), ale poza tym powinieneś szukać innych rozwiązań. –

0

Jeśli używasz mechanizmu łączenia (fabrycznie klienta http) lub mechanizmu równoważenia obciążenia (eureka) z Twoim RestTemplate, nie będziesz mieć luksusu tworzenia new RestTemplate dla każdej klasy. Jeśli dzwonisz do więcej niż jednej usługi, nie możesz użyć numeru setErrorHandler, ponieważ w przypadku wszystkich Twoich zgłoszeń byłby on używany globalnie.

W takim przypadku lepszym rozwiązaniem będzie złapanie HttpStatusCodeException.

Jedyną inną dostępną opcją jest zdefiniowanie wielu instancji RestTemplate przy użyciu adnotacji @Qualifier.

Również - ale to jest mój własny gust - podoba mi się moja obsługa błędów ściśle przylegających do moich połączeń.