Używam interfejsu RESTful JSON API przy użyciu funkcji Spring RestTemplate
i Jacksona. W niektórych przypadkach możemy otrzymać Status 401
(Nieautoryzowane) odpowiedź z niestandardowym JSON ciała, która jest wyznaczona przez producenta API, a wygląda to tak:Jak przeanalizować treść odpowiedzi w języku Java, gdy żądanie HTTP ma status powrotu 401
{
"code": 123,
"message": "Reason for the error"
}
Musimy przeanalizować ciało i użyć właściwości code
w naszej logice biznesowej.
Jest to obiekt Java odpowiedź błąd musimy zanalizować do:
public class CustomError {
@JsonProperty
private Integer code;
@JsonProperty
private String message;
public Integer getCode() {
return code;
}
public String getMessage() {
return message;
}
}
A inny system obsługi błędów, aby to zrobić:
public class CustomErrorHandler extends DefaultResponseErrorHandler {
private RestTemplate restTemplate;
private ObjectMapper objectMapper;
private MappingJacksonHttpMessageConverter messageConverter;
@Override
public boolean hasError(ClientHttpResponse response) throws IOException {
return super.hasError(response);
}
@Override
public void handleError(final ClientHttpResponse response) throws IOException {
try {
CustomError error =
(CustomError) messageConverter.read(CustomError.class, response);
throw new CustomErrorIOException(error, error.getMessage());
} catch (Exception e) {
// parsing failed, resort to default behavior
super.handleError(response);
}
}
}
Procedura obsługi błędu nie powiedzie się z HttpMessageNotReadableException
w próbie blok:
"Nie można odczytać JSON: nie można ponowić próby z powodu autoryzacji serwera, w trybie strumieniowym"
To jak ja wysyłania żądań:
restTemplate.postForObject(url, pojoInstance, responseClass);
Jeżeli ten sam wniosek został wykonany ze zwykłego starego programu klienckiego reszta, jak listonosz otrzyma oczekiwanej odpowiedzi JSON. Zakładam więc, że problem może dotyczyć implementacji Springa ClientHttpResponse
, która w jakiś sposób nie pozwala na dostęp do treści odpowiedzi, w przypadku statusu 401.
Czy rzeczywiście można przeanalizować treść odpowiedzi?
Aktualizacja
Z tego, co badane, klasa RestTemplate
wykorzystuje ClientHttpResponse
co z kolei tworzy sun.net.www.protocol.http.HttpURLConnection
który zapewnia strumień wejściowy. Jest tam, gdzie strumień wejściowy jest zaniedbane i IOException
jest wyrzucany:
nie można powtórzyć ze względu na uwierzytelnianie serwera, w trybie strumieniowania
Więc Realizacja HttpURLConnection
„s jest przyczyną problemu .
Czy uda się uniknąć tego problemu? Być może powinniśmy użyć alternatywnej implementacji, która nie ignoruje treści odpowiedzi w przypadku kodu statusu błędu? Czy możesz polecić jakieś alternatywy?
Próbowałem tego rozwiązania, ale wygląda na to, że nie działa. Wyjątek jest faktycznie zgłaszany, ale strumień odpowiedzi nie zawiera żadnych danych. Jeśli spróbuję tego samego żądania z POSTMAN, ciało odpowiedzi zawiera ciało, więc wydaje się znowu problemem RestTemplate. – Nikolay
Znalazłem błąd, który opisuje problem, który masz w https://jira.spring.io/browse/SPR-9999. Pochodzi z zeszłego roku, ale być może jeszcze nie zostało to naprawione. Sugeruje użycie innej fabryki, aby zastosować inną implementację klienta (szablon RestTemplate = new RestTemplate (nowy HttpComponentsClientHttpRequestFactory()); – Marios
@Marios, dziękuję za twoje wysiłki.) Używałem wcześniej 'SimpleClientHttpConnectionFactory'. mnie przy użyciu 'HttpComponentsClientHttpRequestFactory' - być może wyżej wspomniany' sun.net.www.protocol.http.HttpURLConnection' nie jest przez niego używany –