背景:在项目A代码内部,调用项目B的restful接口C,我们采用了RestTemplate进行调用,但是调用过程中,一直不能正常返回数据,日志显示参数存在乱码(有个参数的值是中文)
乱码原因:请求方式是POST,但是我们把参数都放在了url的?后面,参数传递形式与GET请求一样!!!
由于请求方式是POST,所以需要将参数放在body里面进行传递,并且参数需要用MultiValueMap结构体装载,如下所示(RestTemplate的调用改为如下就好了):
方式一:
if (method == HttpMethod.POST) { MultiValueMap<String, Object> postParameters = new LinkedMultiValueMap<>(); map.forEach((k, v) -> { postParameters.add(k, v.toString()); }); return JSON.parseObject(restTemplate.postForObject(url, postParameters, String.class)); }
方式二:
postParam: post请求时body里面的参数
url: 含url后跟的其他参数
restTemplate.postForObject(url.toString(), new HttpEntity<>(postParam), String.class);
注意,在启动类里加载restTemplate时,需要设置为UTF-8
@Bean public RestTemplate getRestTemplate() { RestTemplate restTemplate = new RestTemplate(); restTemplate.getMessageConverters().add(0, new StringHttpMessageConverter(Charset.forName("UTF-8"))); return restTemplate; }
方式三:
适合于 url 后面既有 param 又有 body 的 post 请求
public void testPostRestTemplate() { String url = "http://localhost:9999/xxx/xxx"; // url 后面的 param 参数,即 url 问号后面的参数信息 Map<String, Object> urlMap = new HashMap<>(5); urlMap.put("urlKey1", "urlValue1"); urlMap.put("urlKey2", "urlValue2"); urlMap.put("urlKey3", "urlValue3"); urlMap.put("urlKey4", "urlValue4"); urlMap.put("urlKey5", "urlValue5"); // 将 param 参数追加到 url 后面 StringBuilder sb = new StringBuilder(url); if (!CollectionUtils.isEmpty(urlMap)) { sb.append("?"); urlMap.forEach((k, v) -> { sb.append(k).append("=").append(v).append("&"); }); sb.deleteCharAt(sb.length() - 1); } // post 请求里面的 body 内容 Map<String, String> bodyMap = new HashMap<>(); bodyMap.put("bodyKey1", "bodyValue1"); // 设置 headers HttpHeaders httpHeaders = new HttpHeaders(); MediaType type = MediaType.parseMediaType("application/json;charset=UTF-8"); httpHeaders.setContentType(type); HttpEntity<Map<String, Object>> objectHttpEntity = new HttpEntity(bodyMap, httpHeaders); ResponseEntity<Object> responseResultResponseEntity = restTemplate.postForEntity(sb.toString(), objectHttpEntity, Object.class); Object res = responseResultResponseEntity.getBody(); System.out.println(res); }