今天也遇到了这个问题,折腾半天,终于定位到问题所在。先贴下自己找到的答案: [图片] 大致意思就是新版本的Spring框架不再在请求头里面自动添加"Content-Length"了,缺少这个请求头,就是我们出错的原因。 再说解决方法,提供3种思路供大家参考: 方法1:不用RestTemplate了,换一个客户端,比如hutool里面的HttpRequest; public WechatPhoneResponse getUserPhoneNumber(String code) { WechatAccessTokenResponse accessTokenResponse = this.getAccessToken(); String url = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=" + accessTokenResponse.getAccessToken(); String body = String.format("{\"code\":\"%s\"}", code); HttpResponse response = HttpRequest.post(url) .body(body) .timeout(30000) .execute(); try { log.info("response body : {}", response.body()); return objectMapper.readValue(response.body(), WechatPhoneResponse.class); } catch (JsonProcessingException e) { throw new RuntimeException(e); } } 方法2:自己手动计算content-length,加到headers里面去 public WechatPhoneResponse getUserPhoneNumber(String code) { WechatAccessTokenResponse accessTokenResponse = this.getAccessToken(); String accessToken = accessTokenResponse.getAccessToken(); if (accessToken == null || accessToken.isEmpty()) { throw new RuntimeException("Failed to obtain access token"); } String url = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=" + accessToken; Map<String, Object> body = Map.of("code", code); HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); // 将请求体转换为字节数组,并计算它的长度 String jsonBody; try { jsonBody = objectMapper.writeValueAsString(body); } catch (JsonProcessingException e) { throw new RuntimeException(e); } byte[] bodyBytes = jsonBody.getBytes(StandardCharsets.UTF_8); int contentLength = bodyBytes.length; headers.setContentLength(contentLength); HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<>(body, headers); log.debug("Request URL: {}", url); log.debug("Request Body: {}", body); log.debug("Request Headers: {}", headers); try { return restTemplate.postForObject(url, requestEntity, WechatPhoneResponse.class); } catch (HttpClientErrorException e) { log.error("HTTP Status Code: {}", e.getStatusCode()); log.error("Response Body: {}", e.getResponseBodyAsString()); throw e; 方法3:向最前面描述的那样,修改RestTemplate的配置,把缓冲加回去; @Bean public RestTemplate restTemplate() { RestTemplate restTemplate = builder .setConnectTimeout(Duration.ofSeconds(15)) .setReadTimeout(Duration.ofSeconds(15)) .build(); configureMessageConverters(restTemplate); return restTemplate; }
小程序手机号解析接口一直报 412 Precondition Failed: [no body]?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; }
2024-08-08今天也遇到了这个问题,折腾半天,终于定位到问题所在。先贴下自己找到的答案: [图片] 大致意思就是新版本的Spring框架不再在请求头里面自动添加"Content-Length"了,缺少这个请求头,就是我们出错的原因。 再说解决方法,提供3种思路供大家参考: 方法1:不用RestTemplate了,换一个客户端,比如hutool里面的HttpRequest; public WechatPhoneResponse getUserPhoneNumber(String code) { WechatAccessTokenResponse accessTokenResponse = this.getAccessToken(); String url = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=" + accessTokenResponse.getAccessToken(); String body = String.format("{\"code\":\"%s\"}", code); HttpResponse response = HttpRequest.post(url) .body(body) .timeout(30000) .execute(); try { log.info("response body : {}", response.body()); return objectMapper.readValue(response.body(), WechatPhoneResponse.class); } catch (JsonProcessingException e) { throw new RuntimeException(e); } } 方法2:自己手动计算content-length,加到headers里面去 public WechatPhoneResponse getUserPhoneNumber(String code) { WechatAccessTokenResponse accessTokenResponse = this.getAccessToken(); String accessToken = accessTokenResponse.getAccessToken(); if (accessToken == null || accessToken.isEmpty()) { throw new RuntimeException("Failed to obtain access token"); } String url = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=" + accessToken; Map<String, Object> body = Map.of("code", code); HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); // 将请求体转换为字节数组,并计算它的长度 String jsonBody; try { jsonBody = objectMapper.writeValueAsString(body); } catch (JsonProcessingException e) { throw new RuntimeException(e); } byte[] bodyBytes = jsonBody.getBytes(StandardCharsets.UTF_8); int contentLength = bodyBytes.length; headers.setContentLength(contentLength); HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<>(body, headers); log.debug("Request URL: {}", url); log.debug("Request Body: {}", body); log.debug("Request Headers: {}", headers); try { return restTemplate.postForObject(url, requestEntity, WechatPhoneResponse.class); } catch (HttpClientErrorException e) { log.error("HTTP Status Code: {}", e.getStatusCode()); log.error("Response Body: {}", e.getResponseBodyAsString()); throw e; 方法3:向最前面描述的那样,修改RestTemplate的配置,把缓冲加回去; @Bean public RestTemplate restTemplate() { RestTemplate restTemplate = builder .setConnectTimeout(Duration.ofSeconds(15)) .setReadTimeout(Duration.ofSeconds(15)) .build(); configureMessageConverters(restTemplate); return restTemplate; }
小程序手机号解析接口一直报 412 Precondition Failed: [no body]?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; }
2024-08-08今天也遇到了这个问题,折腾半天,终于定位到问题所在。先贴下自己找到的答案: [图片] 大致意思就是新版本的Spring框架不再在请求头里面自动添加"Content-Length"了,缺少这个请求头,就是我们出错的原因。 再说解决方法,提供3种思路供大家参考: 方法1:不用RestTemplate了,换一个客户端,比如hutool里面的HttpRequest; public WechatPhoneResponse getUserPhoneNumber(String code) { WechatAccessTokenResponse accessTokenResponse = this.getAccessToken(); String url = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=" + accessTokenResponse.getAccessToken(); String body = String.format("{\"code\":\"%s\"}", code); HttpResponse response = HttpRequest.post(url) .body(body) .timeout(30000) .execute(); try { log.info("response body : {}", response.body()); return objectMapper.readValue(response.body(), WechatPhoneResponse.class); } catch (JsonProcessingException e) { throw new RuntimeException(e); } } 方法2:自己手动计算content-length,加到headers里面去 public WechatPhoneResponse getUserPhoneNumber(String code) { WechatAccessTokenResponse accessTokenResponse = this.getAccessToken(); String accessToken = accessTokenResponse.getAccessToken(); if (accessToken == null || accessToken.isEmpty()) { throw new RuntimeException("Failed to obtain access token"); } String url = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=" + accessToken; Map<String, Object> body = Map.of("code", code); HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); // 将请求体转换为字节数组,并计算它的长度 String jsonBody; try { jsonBody = objectMapper.writeValueAsString(body); } catch (JsonProcessingException e) { throw new RuntimeException(e); } byte[] bodyBytes = jsonBody.getBytes(StandardCharsets.UTF_8); int contentLength = bodyBytes.length; headers.setContentLength(contentLength); HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<>(body, headers); log.debug("Request URL: {}", url); log.debug("Request Body: {}", body); log.debug("Request Headers: {}", headers); try { return restTemplate.postForObject(url, requestEntity, WechatPhoneResponse.class); } catch (HttpClientErrorException e) { log.error("HTTP Status Code: {}", e.getStatusCode()); log.error("Response Body: {}", e.getResponseBodyAsString()); throw e; 方法3:向最前面描述的那样,修改RestTemplate的配置,把缓冲加回去; @Bean public RestTemplate restTemplate() { RestTemplate restTemplate = builder .setConnectTimeout(Duration.ofSeconds(15)) .setReadTimeout(Duration.ofSeconds(15)) .build(); configureMessageConverters(restTemplate); return restTemplate; }
小程序手机号解析接口一直报 412 Precondition Failed: [no body]?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; }
2024-08-08