Spring framework's RestTemplate'i istemci programımda kullanıyorum ve sunucu tarafında bir Json gövdesi ile bir GET isteği tanımladım. Birincil amacım sizinkilerle aynı: istek çok sayıda parametreye sahip olduğunda, bunları vücuda koymak, onları uzun süreli URI dizesine koymaktan daha düzenli görünüyor. Evet?
Ancak, ne yazık ki, çalışmıyor! Sunucu tarafı aşağıdaki istisnayı attı:
org.springframework.http.converter.HttpMessageNotReadableException: Gerekli istek gövdesi eksik ...
Ancak ileti gövdesinin istemci kodum tarafından doğru bir şekilde sağlandığından eminim, bu yüzden sorun nedir?
RestTemplate.exchange () yöntemini izledim ve aşağıdakileri buldum:
// 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();
}
...
}
}
Lütfen executeInternal () yönteminde, 'bufferedOutput' giriş bağımsız değişkeninin kodum tarafından sağlanan ileti gövdesini içerdiğine dikkat edin. Hata ayıklayıcıdan gördüm.
Ancak, preparConnection () nedeniyle, executeInternal () öğesindeki getDoOutput () yöntemi her zaman false değerini döndürür, bu da bufferedOutput öğesini tamamen yok sayılır! Çıkış akışına kopyalanmaz.
Sonuç olarak, sunucu programım ileti gövdesi almadı ve bu özel durumu attı.
Bu, Bahar çerçevesinin RestTemplate'i hakkında bir örnektir. Mesele şu ki, ileti gövdesi artık HTTP spec tarafından yasaklanmış olmasa bile, bazı istemci veya sunucu kitaplıkları veya çerçeveleri hala eski spesifikasyona uyup mesaj gövdesini GET isteğinden reddedebilir.