RestTemplate乱码总结


(一)背景

现在的项目大多用的是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());
        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());
        }
    }