Tôi đang sử dụng RestTemplate của khung công tác Spring trong chương trình máy khách của mình và, ở phía máy chủ, tôi đã xác định một yêu cầu GET với phần thân Json. Mục đích chính của tôi giống như của bạn: khi yêu cầu có nhiều tham số, việc đặt chúng vào cơ thể có vẻ gọn gàng hơn so với việc đưa chúng vào chuỗi URI kéo dài. Đúng?
Nhưng, thật đáng buồn, nó không hoạt động! Phía máy chủ đã ném ngoại lệ sau:
org.springframework.http.converter.HttpMessageNotReadableException: Yêu cầu cơ thể yêu cầu bị thiếu ...
Nhưng tôi khá chắc chắn rằng phần thân thông điệp được cung cấp chính xác bởi mã khách hàng của tôi, vậy có gì sai?
Tôi bắt nguồn từ phương thức RestTemplate.exchange () và tìm thấy như sau:
// 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();
}
...
}
}
Xin lưu ý rằng trong phương thức execI Internalal (), đối số đầu vào 'bufferedOutput' chứa phần thân thông điệp được cung cấp bởi mã của tôi. Tôi đã nhìn thấy nó thông qua trình gỡ lỗi.
Tuy nhiên, do readyConnection (), getDoOutput () trong execI Internalal () luôn trả về false, do đó, làm cho bufferedOutput hoàn toàn bị bỏ qua! Nó không được sao chép vào luồng đầu ra.
Do đó, chương trình máy chủ của tôi không nhận được thông báo nào và đã ném ngoại lệ đó.
Đây là một ví dụ về RestTemplate của khung công tác Spring. Vấn đề là, ngay cả khi phần thân thông điệp không còn bị cấm bởi thông số HTTP, một số thư viện hoặc khung máy chủ hoặc máy khách vẫn có thể tuân thủ thông số cũ và từ chối phần thân thông báo từ yêu cầu GET.