zoukankan      html  css  js  c++  java
  • 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<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());
            }
        }
  • 相关阅读:
    Docker的ubuntu镜像安装的容器无ifconfig和ping命令的解决
    高德地图api实现地址和经纬度的转换(python)
    数据结构:优先队列 基于堆实现(python版)
    数据结构:优先队列 基于list实现(python版)
    数据结构:堆排序 (python版) 小顶堆实现从大到小排序 | 大顶堆实现从小到大排序
    数据结构:基于list实现二元表达式(python版)
    数据结构:二叉树 基于list实现(python版)
    python之数据库内置方法以及pymysql的使用
    Python之内置函数一
    mysql数据库的安装和基本使用
  • 原文地址:https://www.cnblogs.com/vincentren/p/13713114.html
Copyright © 2011-2022 走看看