Я использую RestTemplate среды Spring в моей клиентской программе и на стороне сервера я определил запрос 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' содержит тело сообщения, предоставленное моим кодом. Я видел это через отладчик.
Однако из-за prepareConnection () getDoOutput () в executeInternal () всегда возвращает false, что, в свою очередь, делает bufferedOutput полностью игнорируемым! Он не копируется в выходной поток.
Следовательно, моя серверная программа не получила тела сообщения и вызвала это исключение.
Это пример шаблона RestTemplate среды Spring. Дело в том, что даже если тело сообщения больше не запрещено спецификацией HTTP, некоторые клиентские или серверные библиотеки или инфраструктуры могут по-прежнему соответствовать старой спецификации и отклонять тело сообщения из запроса GET.