2015-09-30 16 views
7

Buduję aplikację przy użyciu Spring Boot. Ta aplikacja jest rozpowszechniana, co oznacza, że ​​mam wiele interfejsów API, które wywołują się nawzajem.Spring Boot, jak ignorować wyjątki HttpStatus

Jedna z moich podstawowych usług współdziała z bazą danych i odpowiada żądanymi danymi. Jeżeli wniosek do ID nieistniejącego składa, że ​​odpowiedź z 404 httpStatus:

return new ResponseEntity<>(HttpStatus.NOT_FOUND); 

(To samo z 400 błędu niektórych operacji, lub 204 do usuwania wpisu, etc).

Problem polega na tym, że mam inne aplikacje Spring Boot, które wywołują te interfejsy API, wyrzucają wyjątek org.springframework.web.client.HttpClientErrorException: 404 Not Found, gdy żądają w tym przykładzie nieistniejącego wpisu. Ale kod statusu 404 jest przeznaczony i nie powinien zwracać tego wyjątku (powodując, że mój wyłącznik Hystrix wywoła funkcję zastępczą).

Jak mogę rozwiązać ten problem?

Powołanie do służby jest realizowany w ten sposób w moim kodu: ResponseEntity<Object> data = restTemplate.getForEntity(url, Object.class);

Moja RestTemplate jest skonfigurowany tak:

private RestTemplate restTemplate = new RestTemplate(); 
+0

Jak skonfigurować "RestTemplate"? –

+0

@SotiriosDelimanolis Zaktualizowałem pytanie w sposób, w jaki konfiguruję mój RestTemplate – Kaj

Odpowiedz

10

sprężyny RestTemplate używa ResponseErrorHandler do obsługi błędów w odpowiedziach. Ten interfejs umożliwia zarówno ustalenie, czy odpowiedź zawiera błąd (ResponseErrorHandler#hasError(ClientHttpResponse)), jak i sposób obsługi (ResponseErrorHandler#handleError(ClientHttpResponse)).

Można ustawić RestTemplate „s ResponseErrorHandler z RestTemplate#setErrorHandler(ResponseErrorHandler) którego javadoc stany

Domyślnie RestTemplate używa DefaultResponseErrorHandler.

Ten Domyślna implementacja

[...] sprawdza kod stanu na ClientHttpResponse: dowolny kod z serii HttpStatus.Series.CLIENT_ERROR lub HttpStatus.Series.SERVER_ERROR jest uważane za błąd. To zachowanie można zmienić, zastępując metodę za pomocą metody .

W przypadku błędu, rzuca wyjątek, który widzisz.

Jeśli chcesz zmienić to zachowanie, możesz podać własną implementację ResponseErrorHandler (może przez przesłonięcie DefaultResponseErrorHandler), która nie uważa 4xx za błąd lub nie rzuca wyjątku.

Na przykład

restTemplate.setErrorHandler(new ResponseErrorHandler() { 
    @Override 
    public boolean hasError(ClientHttpResponse response) throws IOException { 
     return false; // or whatever you consider an error 
    } 

    @Override 
    public void handleError(ClientHttpResponse response) throws IOException { 
     // do nothing, or something 
    } 
}); 

Następnie można sprawdzić kod statusu ResponseEntity zwróconej przez getForEntity i obsługiwać go samodzielnie.

+0

Działa sprawnie, wielkie dzięki. Nie wiedziałem o tym. – Kaj

+0

Wydaje się, że to nie działa podczas korzystania z Spring Cloud 1.0.2 lub SR3. Procedura obsługi błędów nigdy nie jest wywoływana, a wyjątek jest generowany niezależnie. – RubesMN

+0

@RubesMN Nie wiem, Spring Cloud. Polecam zadać nowe pytanie z wszystkimi istotnymi szczegółami do odtworzenia zachowań, które widzisz. –