私はクライアントプログラムでSpringフレームワークのRestTemplateを使用しており、サーバー側で、Json本文を使用してGETリクエストを定義しています。私の主な目的はあなたのものと同じです。リクエストに多数のパラメーターがある場合、それらを本文に入れると、長い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()により、executeInternal()のgetDoOutput()は常にfalseを返すため、bufferedOutputは完全に無視されます。出力ストリームにはコピーされません。
その結果、サーバープログラムはメッセージ本文を受信せず、その例外をスローしました。
これは、SpringフレームワークのRestTemplateの例です。重要なのは、メッセージ本文がHTTP仕様で禁止されなくなっても、一部のクライアントまたはサーバーライブラリまたはフレームワークは古い仕様に準拠し、GETリクエストからのメッセージ本文を拒否する可能性があるということです。