(一)背景
现在的项目大多用的是spring框架,然后就方便的直接用RestTemplate,但是在实际使用时常常会发现出现乱码的情况,今天总结下这些情况
(二)request乱码
request乱码就是,请求别人的接口,比如别人需要你的编码格式是“UTF-8”,而我的是“ISO-8859-1”,那么别人解析我的body,就会出现乱码的情况,这种情况的解决很简单。
在这边文章中,我已经对RestTemplate源码做了分析,在写body时,会先从我们的请求head中看是否有设置charset,如果没有,HttpMessageConverter会用他们默认的编码格式,比如StringHttpMessageConverter的默认编码格式就是“ISO-8859-1,所以我们只需要这样子设置就行
HttpHeaders headers = new HttpHeaders(); MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8"); headers.setContentType(type); headers.add("Accept", MediaType.APPLICATION_JSON.toString()); HttpEntity request = new HttpEntity<>(jsonObject, headers); JSONObject response = restTemplate.postForObject("http://127.0.0.1:8089/getBodyTest", request, JSONObject.class);
(三)response乱码
response乱码就是,请求别人的接口,别人返回给我们的body编码格式是“UTF-8”,而我的是“ISO-8859-1”,那么我们解析别人的body就会出现乱码。
这种问题的出现是因为,别人返回的head中未设置charset,RestTemplate就会使用HttpMessageConverter的默尔编码了。因为是别人返回的内容,我们无法串改别人的返回head,所以需要修改我们的HttpMessageConverter的编码格式,以将别人的返回body转换为string为例
String result = restTemplate.postForObject("http://127.0.0.1:8089/getBodyTest", request, String.class);
这样子调用,我们就会采用StringHttpMessageConverter的默认编码格式就是“ISO-8859-1”,那么将会出现乱码。我们加这一行就可以解决string类型的乱码问题
restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
String result = restTemplate.postForObject("http://127.0.0.1:8089/getBodyTest", request, String.class);
为什么set的是1这个位置呢?
因为在RestTemplate初始化中StringHttpMessageConverter是在第1的位置,第0是ByteArrayHttpMessageConverter
public RestTemplate() { this.messageConverters.add(new ByteArrayHttpMessageConverter()); this.messageConverters.add(new StringHttpMessageConverter()); this.messageConverters.add(new ResourceHttpMessageConverter()); this.messageConverters.add(new SourceHttpMessageConverter<Source>()); this.messageConverters.add(new AllEncompassingFormHttpMessageConverter()); if (romePresent) { this.messageConverters.add(new AtomFeedHttpMessageConverter()); this.messageConverters.add(new RssChannelHttpMessageConverter()); } if (jackson2XmlPresent) { this.messageConverters.add(new MappingJackson2XmlHttpMessageConverter()); } else if (jaxb2Present) { this.messageConverters.add(new Jaxb2RootElementHttpMessageConverter()); } if (jackson2Present) { this.messageConverters.add(new MappingJackson2HttpMessageConverter()); } else if (gsonPresent) { this.messageConverters.add(new GsonHttpMessageConverter()); } }