Estoy usando el RestTemplate de Spring Framework en mi programa cliente y, en el lado del servidor, definí una solicitud GET con un cuerpo Json. Mi propósito principal es el mismo que el suyo: cuando la solicitud tiene numerosos parámetros, ponerlos en el cuerpo parece más ordenado que ponerlos en la cadena de URI prolongada. ¿Si?
Pero, lamentablemente, ¡no está funcionando! El lado del servidor lanzó la siguiente excepción:
org.springframework.http.converter.HttpMessageNotReadableException: falta el cuerpo de solicitud requerido ...
Pero estoy bastante seguro de que el código del cliente proporciona correctamente el cuerpo del mensaje, entonces, ¿qué pasa?
Seguí el método RestTemplate.exchange () y encontré lo siguiente:
// 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();
}
...
}
}
Tenga en cuenta que en el método executeInternal (), el argumento de entrada 'bufferedOutput' contiene el cuerpo del mensaje proporcionado por mi código. Lo vi a través del depurador.
Sin embargo, debido a prepareConnection (), getDoOutput () en executeInternal () siempre devuelve falso, lo que a su vez hace que el bufferedOutput sea completamente ignorado. No se copia en la secuencia de salida.
En consecuencia, mi programa de servidor no recibió el cuerpo del mensaje y lanzó esa excepción.
Este es un ejemplo sobre el RestTemplate del marco Spring. El punto es que, incluso si el cuerpo del mensaje ya no está prohibido por la especificación HTTP, algunas bibliotecas o marcos de clientes o servidores aún pueden cumplir con la especificación anterior y rechazar el cuerpo del mensaje de la solicitud GET.