SpringBoot Java8发送application/x-www-form-urlencoded POST请求报错
问题分析与解决方案
核心问题排查
请求体格式不匹配
你设置了ContentType为application/x-www-form-urlencoded,但实际传递的是JSON字符串(properties.toString()),而该格式要求的是key1=value1&key2=value2的键值对形式,这是接口报错的主要原因。响应字段名错误
Postman返回的token字段是access_token,但代码中用accessToken去解析,会导致无法正确获取值。ErrorModel输出问题
返回的org.zwz.vas.internal.api.model.ErrorModel@16dd359c是对象默认的toString输出,说明该类未重写toString()方法,无法返回可读的错误信息。
修正后的代码
public String getNewAccesToken() { try { // 用MultiValueMap存储表单键值对,适配application/x-www-form-urlencoded格式 MultiValueMap<String, String> formData = new LinkedMultiValueMap<>(); formData.add("client_id", clientId); formData.add("client_secret", clientSecret); formData.add("grant_type", grantType); HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); headers.set("Cookie", cookie); // 请求体传入MultiValueMap,Spring会自动转成表单格式 HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(formData, headers); log.debug(requestEntity); ResponseEntity<String> response = restTemplate.exchange(requestUrl, HttpMethod.POST, requestEntity, String.class); log.debug("---------------------------------"); log.debug(response); if (Util.isJSONValid(response.getBody())) { JsonParser parser = new JsonParser(); JsonObject jsonString = (JsonObject) parser.parse(response.getBody()); // 匹配Postman返回的字段名access_token return jsonString.get("access_token").getAsString(); } else { error.setCode(ConstantGateway.JSON_ERROR_CODE); error.setMessage(ConstantGateway.JSON_ERROR_STATUS); // 建议重写ErrorModel的toString()方法,或手动构建错误字符串 return String.format("Error: code=%s, message=%s", error.getCode(), error.getMessage()); } } catch (HttpStatusCodeException e) { error.setCode(String.valueOf(e.getStatusCode().value())); error.setMessage(e.getResponseBodyAsString()); return String.format("Error: code=%s, message=%s", error.getCode(), error.getMessage()); } catch (Exception e) { error.setCode(ConstantGateway.IL_INTERNAL_ERROR_CODE); error.setMessage(e.getMessage()); return String.format("Error: code=%s, message=%s", error.getCode(), error.getMessage()); } }
关键改动说明
- 表单请求体处理:使用
MultiValueMap(推荐LinkedMultiValueMap)存储表单参数,Spring的RestTemplate会自动将其序列化为application/x-www-form-urlencoded格式的请求体,和Postman的请求格式完全一致。 - 字段名修正:将
jsonString.get("accessToken")改为jsonString.get("access_token"),匹配接口返回的字段名。 - 错误信息优化:替换
error.toString()为手动构建的可读错误字符串,或者给ErrorModel类重写toString()方法,例如:@Override public String toString() { return "ErrorModel{" + "code='" + code + '\'' + ", message='" + message + '\'' + '}'; }
内容的提问来源于stack exchange,提问作者Mohamde amine Karek
相关产品推荐
相关产品推荐

