ฉันใช้ RestTemplate ของ Spring framework ในโปรแกรมไคลเอนต์ของฉันและที่ฝั่งเซิร์ฟเวอร์ฉันได้กำหนดคำขอ GET ด้วยเนื้อความ Json จุดประสงค์หลักของฉันก็เหมือนกับของคุณ: เมื่อคำขอมีพารามิเตอร์จำนวนมากการใส่ไว้ในร่างกายดูเหมือนจะเป็นระเบียบเรียบร้อยกว่าการใส่ไว้ในสตริง 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' มีเนื้อหาข้อความที่ระบุโดยรหัสของฉัน ฉันเห็นมันผ่านตัวดีบั๊ก
อย่างไรก็ตามเนื่องจากการเตรียมความพร้อมการเชื่อมต่อ (), getDoOutput () ใน executeInternal () มักจะส่งกลับเท็จซึ่งในทางกลับกันทำให้ bufferedOutput ถูกเพิกเฉยอย่างสมบูรณ์! มันไม่ได้คัดลอกไปยังสตรีมเอาต์พุต
ดังนั้นโปรแกรมเซิร์ฟเวอร์ของฉันไม่ได้รับเนื้อหาข้อความและส่งข้อยกเว้นนั้น
นี่คือตัวอย่างเกี่ยวกับ RestTemplate ของ Spring framework ประเด็นก็คือแม้ว่าเนื้อหาข้อความจะไม่ได้รับอนุญาตจากข้อกำหนด HTTP อีกต่อไปไคลเอนต์หรือเซิร์ฟเวอร์ไลบรารีหรือกรอบงานบางอย่างอาจยังคงสอดคล้องกับข้อมูลจำเพาะเก่าและปฏิเสธเนื้อหาข้อความจากคำขอ GET