Korzystam z RestTemplate frameworka Spring w moim programie klienckim i po stronie serwera zdefiniowałem żądanie GET z treścią Json. Mój główny cel jest taki sam jak twój: gdy żądanie ma wiele parametrów, umieszczenie ich w ciele wydaje się bardziej uporządkowane niż umieszczenie ich w przedłużonym ciągu URI. Tak?
Ale niestety to nie działa! Po stronie serwera zgłoszono następujący wyjątek:
org.springframework.http.converter.HttpMessageNotReadableException: Brak wymaganej treści żądania ...
Ale jestem prawie pewien, że treść mojego kodu klienta została poprawnie dostarczona, więc co jest nie tak?
Prześledziłem metodę RestTemplate.exchange () i znalazłem:
// SimpleClientHttpRequestFactory.class
public class SimpleClientHttpRequestFactory implements ClientHttpRequestFactory, AsyncClientHttpRequestFactory {
...
protected void prepareConnection(HttpURLConnection connection, String httpMethod) throws IOException {
...
if (!"POST".equals(httpMethod) && !"PUT".equals(httpMethod) && !"PATCH".equals(httpMethod) && !"DELETE".equals(httpMethod)) {
connection.setDoOutput(false);
} else {
connection.setDoOutput(true);
}
...
}
}
// SimpleBufferingClientHttpRequest.class
final class SimpleBufferingClientHttpRequest extends AbstractBufferingClientHttpRequest {
...
protected ClientHttpResponse executeInternal(HttpHeaders headers, byte[] bufferedOutput) throws IOException {
...
if (this.connection.getDoOutput() && this.outputStreaming) {
this.connection.setFixedLengthStreamingMode(bufferedOutput.length);
}
this.connection.connect();
if (this.connection.getDoOutput()) {
FileCopyUtils.copy(bufferedOutput, this.connection.getOutputStream());
} else {
this.connection.getResponseCode();
}
...
}
}
Zauważ, że w metodzie executeInternal () argument wejściowy „bufferedOutput” zawiera treść komunikatu dostarczoną przez mój kod. Widziałem to przez debugger.
Jednak z powodu preparConnection () funkcja getDoOutput () w executeInternal () zawsze zwraca false, co z kolei powoduje całkowite zignorowanie bufferedOutput! Nie jest kopiowany do strumienia wyjściowego.
W związku z tym mój program serwera nie otrzymał treści wiadomości i zgłosił ten wyjątek.
To jest przykład RestTemplate frameworka Spring. Chodzi o to, że nawet jeśli treść komunikatu nie jest już zabroniona przez specyfikację HTTP, niektóre biblioteki lub struktury klienta lub serwera mogą nadal być zgodne ze starą specyfikacją i odrzucić treść wiadomości z żądania GET.