I am using the Spring framework's RestTemplate in my client programme and, at the server-side, I defined a GET request with a Json body. My primary purpose is the same as yours: when the request has numerous parameters, putting them in the body seems tidier than putting them in the prolonged URI string. Yes?
But, sadly, it's not working! The server-side threw the following exception:
org.springframework.http.converter.HttpMessageNotReadableException: Required request body is missing...
But I am pretty sure the message body is correctly provided by my client code, so what's wrong?
I traced into the RestTemplate.exchange() method and found the following:
// 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();
}
...
}
}
Please notice that in the executeInternal() method, the input argument 'bufferedOutput' contains the message body provided by my code. I saw it through the debugger.
However, due to the prepareConnection(), the getDoOutput() in executeInternal() always returns false which, in turn, makes the bufferedOutput completely ignored! It's not copied into the output stream.
Consequently, my server programme received no message body and threw that exception.
This is an example about the RestTemplate of the Spring framework. The point is that, even if the message body is no longer forbidden by the HTTP spec, some client or server libraries or frameworks might still comply with the old spec and reject the message body from the GET request.