Estou usando o RestTemplate da estrutura Spring no meu programa cliente e, no lado do servidor, defini uma solicitação GET com um corpo Json. Meu objetivo principal é o mesmo que o seu: quando a solicitação possui vários parâmetros, colocá-los no corpo parece mais organizado do que colocá-los na cadeia URI prolongada. Sim?
Mas, infelizmente, não está funcionando! O lado do servidor lançou a seguinte exceção:
org.springframework.http.converter.HttpMessageNotReadableException: o corpo da solicitação necessária está ausente ...
Mas tenho certeza de que o corpo da mensagem é fornecido corretamente pelo código do meu cliente, então o que há de errado?
Eu rastreei o método RestTemplate.exchange () e encontrei o seguinte:
// 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();
}
...
}
}
Observe que no método executeInternal (), o argumento de entrada 'bufferedOutput' contém o corpo da mensagem fornecido pelo meu código. Eu vi através do depurador.
No entanto, devido ao prepareConnection (), o getDoOutput () em executeInternal () sempre retorna false, o que, por sua vez, torna o bufferedOutput completamente ignorado! Não é copiado no fluxo de saída.
Consequentemente, meu programa de servidor não recebeu nenhum corpo de mensagem e lançou essa exceção.
Este é um exemplo sobre o RestTemplate da estrutura Spring. O ponto é que, mesmo que o corpo da mensagem não seja mais proibido pela especificação HTTP, algumas bibliotecas ou estruturas de clientes ou servidores ainda podem estar em conformidade com a especificação antiga e rejeitar o corpo da mensagem da solicitação GET.