Я використовую програму RestTemplate Spring Framework у своїй програмі клієнта, і на стороні сервера я визначив GET-запит з тілом Json. Моє основне призначення те саме, що і ваше: коли запит має численні параметри, розміщення їх у тілі здається акуратнішим, ніж введення їх у тривалий рядок URI. Так?
Але, на жаль, це не працює! Сторона сервера кинула таке виняток:
org.springframework.http.converter.HttpMessageNotReadableException: обов'язковий орган запиту відсутній ...
Але я впевнений, що тіло повідомлень правильно надано моїм клієнтським кодом, і що не так?
Я простежив метод RestTemplate.exchange () і виявив наступне:
// 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();
}
...
}
}
Зауважте, що у методі ExecuteInternal () вхідний аргумент 'bufferedOutput' містить тіло повідомлення, надане моїм кодом. Я бачив це через налагоджувач.
Однак, завдяки PripravConnection (), getDoOutput () у ExecuteInternal () завжди повертає помилку, що, у свою чергу, робить забуференний вихід повністю ігнорований! Він не скопійований у вихідний потік.
Отже, моя серверна програма не отримала жодного тіла повідомлення і кинула це виняток.
Це приклад про RestTemplate рамки Весна. Справа в тому, що навіть якщо тіло повідомлення більше не заборонено специфікацією HTTP, деякі бібліотеки клієнта або сервера або рамки все ще можуть відповідати старій специфікації і відхиляти тіло повідомлення з GET-запиту.