public String getPhoneNumber(String phoneCode) {
JSONObject params = new JSONObject();
params.put("code", phoneCode);
String url = MessageFormat.format("https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token={0}", getAccessToken());
JSONObject reObj = restTemplate.postForObject(url, params, JSONObject.class);
if (reObj != null && reObj.containsKey("errcode")) {
log.info(reObj.toJSONString());
if (reObj.getInteger("errcode") == 0) {
Code2PhoneNumberResponse code2PhoneNumberResponse = JSONObject.parseObject(reObj.toJSONString(), Code2PhoneNumberResponse.class);
return code2PhoneNumberResponse.getPhoneInfo().getPurePhoneNumber();
}
}
return null;
}
参见楼下的解释,其实是微信会检查Content-Length参数,但Spring Framework 6.1以后请求不再设置该参数(可以参加SimpleClientHttpRequestFactory中的setBufferRequestBody说明);另外可以debug看一下请求报文中的{Transfer-Encoding: chunked}
自己在http header中自己设置Content-Length就行了
String body = JSONObject.toJSONString(params); HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); headers.setContentLength(body.getBytes(StandardCharsets.UTF_8).length); HttpEntity entity = new HttpEntity<>(body, headers); ResponseEntity bResp = restTemplate.postForEntity(url, entity, String.class);
这是因为从 Spring Framework 6.1开始,大多数 ClientHttpRequestFactory 实现在将请求体发送到服务器之前不再使用缓冲区。因此,对于某些内容类型(如 JSON) ,不再知道内容大小,也不再设置 Content-Llength 。如果希望像前面那样对请求主体进行缓冲,只需在 BufferingClientHttpRequestFactory 中包装正在使用的 ClientHttpRequestFactory即可
试过spring boot 3.3.0、3.2.6和3.1.2,最终3.1.2是可以的,没有找到具体的原因,希望有大神能够解决。
这里回复一下,不知道是springboot3的问题还是jdk17的问题,解决方案如下
HashMap<String, Object> params = new HashMap<>(); HttpHeaders headers = new HttpHeaders(); params.put("code", phoneCode); HttpEntity<String> entity = new HttpEntity<>(JSON.toJSONString(params), headers); ResponseEntity<String> response = restTemplate.postForEntity(MessageFormat.format(phoneNumberUrl, getAccessToken()), entity, String.class); 换成postForEntity,并且一定要是hashmap