클라이언트 프로그램에서 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 요청에서 메시지 본문을 거부 할 수 있다는 것입니다.