Description
My project use springboot3.1.8 (spring-web 6.0.16) , and I use RestTemplate with Okhttp4.12.0 for making calls to REST endpoints , the initialize code as follows :
@Bean
public RestTemplate restTemplate() {
RestTemplate restTemplate = new RestTemplate();
OkHttpClient client = new OkHttpClient().newBuilder().connectionPool(new ConnectionPool(300, 300, TimeUnit.SECONDS)).build();
OkHttp3ClientHttpRequestFactory httpRequestFactory = new OkHttp3ClientHttpRequestFactory(client);
restTemplate.setRequestFactory(httpRequestFactory);
return restTemplate;
}
and the call code as follows :
@Test
void testGet() {
String getUrl = "https://api.weixin.qq.com/sns/jscode2session";
String body = restTemplate.getForEntity(getUrl, String.class).getBody();
}
@Test
void testPost() {
String postUrl = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=34534543fdgdfg4545";
Map<String, String> bodyMap = Map.of("code", "xxxxx");
String body = restTemplate.postForEntity(postUrl, bodyMap, String.class).getBody();
}
the result as follows:
testGet:{"errcode":41002,"errmsg":"appid missing, rid: 661632da-22de497f-36b92d2a"}
testPost:{"errcode":40001,"errmsg":"invalid credential"}
and when I upgrade my springboot version to 3.2.4(spring-web 6.1.5) , the same code run result as follows:
testGet:{"errcode":41002,"errmsg":"appid missing, rid: 661632da-22de497f-36b92d2a"}
testPost:
org.springframework.web.client.HttpClientErrorException: 412 Precondition Failed: [no body]
at org.springframework.web.client.HttpClientErrorException.create(HttpClientErrorException.java:136)
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:183)
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:137)
at org.springframework.web.client.ResponseErrorHandler.handleError(ResponseErrorHandler.java:63)
at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:942)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:891)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:790)
at org.springframework.web.client.RestTemplate.postForEntity(RestTemplate.java:538)
at com.example.demo.controller.HttpTest.testOkHttpPost(HttpTest.java:28)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
After upgrade , Get request work ok,but post request work error,and then I found the change(spring-web 6.1.X) in wiki
To reduce memory usage in RestClient and RestTemplate, most ClientHttpRequestFactory implementations no longer buffer request bodies before sending them to the server. As a result, for certain content types such as JSON, the contents size is no longer known, and a Content-Length header is no longer set. If you would like to buffer request bodies like before, simply wrap the ClientHttpRequestFactory you are using in a BufferingClientHttpRequestFactory.
so I change My initialize code as follows :
@Bean
public RestTemplate restTemplate() {
RestTemplate restTemplate = new RestTemplate();
OkHttpClient client = new OkHttpClient().newBuilder().connectionPool(new ConnectionPool(300, 300, TimeUnit.SECONDS)).build();
BufferingClientHttpRequestFactory bufferingClientHttpRequestFactory = new BufferingClientHttpRequestFactory(new OkHttp3ClientHttpRequestFactory(client));
restTemplate.setRequestFactory(bufferingClientHttpRequestFactory);
return restTemplate;
}
and I run my code again ,the result as follows:
testGet:
java.lang.IllegalArgumentException: method GET must not have a request body.
at okhttp3.Request$Builder.method(Request.kt:258)
at org.springframework.http.client.OkHttp3ClientHttpRequest.executeInternal(OkHttp3ClientHttpRequest.java:88)
at org.springframework.http.client.AbstractStreamingClientHttpRequest.executeInternal(AbstractStreamingClientHttpRequest.java:70)
at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:66)
at org.springframework.http.client.BufferingClientHttpRequestWrapper.executeInternal(BufferingClientHttpRequestWrapper.java:75)
at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:48)
at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:66)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:889)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:790)
at org.springframework.web.client.RestTemplate.getForEntity(RestTemplate.java:431)
at com.example.demo.controller.HttpTest.testOkHttpGet(HttpTest.java:37)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
testPost:{"errcode":40001,"errmsg":"invalid credential"}
I found , After change(using BufferingClientHttpRequestFactory) , post request work ok , but get request work wrong
so did I miss some configuration? or is there any other suggestions for modifications?