美文网首页
RestTemplate踩坑-乱码【不是中文乱码哦】

RestTemplate踩坑-乱码【不是中文乱码哦】

作者: 罗亮leon | 来源:发表于2017-10-01 10:12 被阅读0次

    前些日子了一个新需求,需要在后台使用http通讯。Spring 的RestTemplate的极简风格让我迷恋上了它,虽然项目中没使用过,但是还是大胆的使用了它,因为它出身名门【spring家族】。

    1. 第一次遇到乱码

    使用RestTemplate代码很简洁,很快就写完了第一个请求。以下使用的是自己对RestTemplate 的封装类。

        @RequestMapping(value = "/request",produces="application/json;charset=UTF-8")
        public String request(@RequestBody(required = false) String requestBody, @RequestHeader HttpHeaders headers){
            String json = null ;
            Map<String,Object> map = new HashMap<String,Object>();
            try {
                String requestURL= headers.getFirst("url");    
               json=HttpClient.postRest(requestURL,requestBody,headers);
            } catch (Exception e) {
                logger.error("remote request error ",e);
                map.put("code",-1);
                map.put("msg","请求失败");
                return JSON.toJSONString(map);
            }
            logger.info("response json : {}",json);
            return json;
        }
    

    第一次请求就乱码了,乱码如下:

    image.png

    2. 请求恢复正常

    后来发现我们使用了自己定义的假域名,本地没有配置hosts,于是我加上了hosts配置,就恢复正常了。

    3. 发布线上再次出现乱码

    我们在自己测试环境一切都很顺利,很快就可以发布上线了。
    最后一个服务发布完毕后开始验证,马上就出现了和第一次乱码一样的问题。
    于是我记起来我们在测试环境的时候是因为我们没有配置host的情况,查了线上hosts情况。
    又感觉不对劲,线上是域名是真是的域名,应该是不需要配置hosts的。
    后面就各种百度,希望有相同的案例。
    搜索到的大多数问题是StringHttpMessageConverter 的默认编码为ISO8859-1导致的乱码。只要把StringHttpMessageConverter 配置成UTF-8或在Header中配置contentType为UTF-8即可解决. 我们这么做了然而没有任何效果。

    4.使用 Apache HttpComponents 替换了 Spring RestTemplate

    这种突发状况暂时没能解决,然而系统一定是要发布的。我们只好把RestTemplate替换成了 Apache 经典的 httpclient组件,然后一切恢复正常。上线成功!

    5.RestTemplate 乱码的根本原因

    这次发布的乱码问题有同事觉得是RestTemplate的一个bug(我也是这么认为的)。于是我决定找出这个bug。第一个要做的就是复现线上出现的问题。

    我在线上机器构建了一个测试的服务,在本地发送请求,果然复现了那个乱码问题。然而同样的代码发布到测试环境却一点问题也没有。

    经过排查发现是我们线上Nginx服务配置 gzip压缩,我们测试环境并没有配置。所以我们看到的乱码其实是gzip格式转String之后的样子,大家再看一下。

    image.png

    网上说的乱码其实只是中文乱码。而我们当时疏忽了这一点。


    image.png

    知道问题就好办啦,我使用JUnit单元测试去掉了header中的gzip。

    image.png

    果然! 所谓的乱码就消失了。
    此次乱码的原因太隐蔽,我们把客户端传过来的header直接用来发送给远程服务,忽视了header中的【gzp参数】,刚好测试环境没配置gzip,线上配置了gzip。测试那么顺利,已发布就懵逼了!

    一切都是巧合!

    分享结束,谢谢观赏!

    相关文章

      网友评论

          本文标题:RestTemplate踩坑-乱码【不是中文乱码哦】

          本文链接:https://www.haomeiwen.com/subject/eepoextx.html