RestTemplate - jak obsłużyć odpowiedź z jeśli spodziewamy się dwóch możliwych typów?

0

W jaki sposób ładnie obsłużyć dwa potencjalne typy które mogą przyjść jako ResponseEntity<?>

Dajmy na to na 404 przychodzi jakiś ErrorDto z całkiem inną strukturą jsona, a na 200 UserDto.

1

Najpierw sprawdzasz status odpowiedzi, później mapujesz?

0

@MrMadMatt:

czyli poprawnym jest takie wywołanie?

ResponseEntity<?> response = restTemplate
  .exchange(url, HttpMethod.GET, request, Object.class);

i potem robić mapowanie?

0

Ja bym robił coś w stylu:

ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.GET, request, String.class);

Aby dostać stringa który jest JSONem a później jakiegoś ifa:

if(response.getStatus().equals(OK)) {
    myClass = gson.fromJson(response.getBody, My.Class);
}

Mniej więcej taki koncept.

3

IMO standardowo dla HTTP status != 2xx zostanie odpalony Spingowy error handler, wiec do parsowania body nawet nie dojdzie. Napisz test i dobrze się przedebuguj przez internale.

https://www.baeldung.com/spring-rest-template-error-handling

0

Polecam zabawki typu OpenAPI - klienta wygeneruje za ciebie i nie musisz się takimi low levelowymi rzeczami przejmować.

3

@Charles_Ray: mówi dobrze, RestTemplate jest zrypany i jak jest 400 albo 500 to rzuca wyjątkiem. Czemu? Nie wiem.

0

Kiedyś poczyniłem taki kod:

public static <T> Either<ResponseEntity<ApiErrorDetails>, ResponseEntity<T>> parseAndGetResponse(ResponseEntity<String> response, Type responseType) {
        if (response.getStatusCode().is2xxSuccessful()) {
            T body = gson.fromJson(response.getBody(), responseType);
            ResponseEntity<T> parsedResponse = new ResponseEntity<>(body, response.getHeaders(), response.getStatusCode());
            return Either.right(parsedResponse);
        }
        ApiErrorDetails body = gson.fromJson(response.getBody(), ApiErrorDetails.class);
        ResponseEntity<ApiErrorDetails> parsedResponse = new ResponseEntity<>(body, response.getHeaders(), response.getStatusCode());
        return Either.left(parsedResponse);
}
ResponseEntity<String> response = restTemplate.getForEntity(...);
var parsedResponse = parseAndGetResponse(response, new TypeToken<UserDto>(){}.getType());

więcej tutaj

5
  1. Nie używać RestTemplate, Java ma już od dawna własnego HttpClienta
  2. Mapować odpowiedź na podstawie status code.
  3. W ogóle nie używać nigdzie gołego klienta http, tylko napisać domenowy wrapper pod konkretny serwis.
0

Mapować odpowiedź na podstawie status code.

No w sumie racja w Javovym rest kliencie możesz wyciągnąc body jako Stringi jak człowiek użyć jakiegoś Jacksona do zmapowania

0

@Charles_Ray:

Pokaz przykładowe uzycie - jak to pożeniłeś z RestTemplate, który rzuca wyjątkami? Nadpisywales ErrorHandler?

Tak można nadpisać podobnie jak to robi TestRestTemplate:

class NoOpResponseErrorHandler extends DefaultResponseErrorHandler {
        public void handleError(ClientHttpResponse response) {}
}

restTemplate.setErrorHandler(new NoOpResponseErrorHandler());
ResponseEntity<String> response = restTemplate.getForEntity(..., String.class);

@Shalom:

Nie używać RestTemplate, Java ma już od dawna własnego HttpClienta

imo jest trochę niskopoziomowy w porównaniu do restTemplate.

0

imo jest trochę niskopoziomowy w porównaniu do restTemplate.

W jaki sposób? Poza tym że trzeba co najwyżej Jacksona jawnie użyć do zmapowania obiektu?

0
scibi_92 napisał(a):

W jaki sposób? Poza tym że trzeba co najwyżej Jacksona jawnie użyć do zmapowania obiektu?

W restTemplate można dodawać interceptory można ustawić root uri jakieś factory też skonfigurować
i nie trzeba za każdym razem ręcznie mapować używając jackson / gson. Nie wiem też jakie możliwości
ma javovy http client bo mało go używałem ale wydaje się, że więcej się trzeba napisać.

1
lookacode1 napisał(a):
scibi_92 napisał(a):

W jaki sposób? Poza tym że trzeba co najwyżej Jacksona jawnie użyć do zmapowania obiektu?

W restTemplate można dodawać interceptory można ustawić root uri jakieś factory też skonfigurować
i nie trzeba za każdym razem ręcznie mapować używając jackson / gson. Nie wiem też jakie możliwości
ma javovy http client bo mało go używałem ale wydaje się, że więcej się trzeba napisać.

Brzmi jak tight-coupling ciaśniejszy niż... może zcenzuruję tutaj.

Zrób wrapper na to, specyficzny dla Twojego przypadku po prostu.

1 użytkowników online, w tym zalogowanych: 0, gości: 1