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

前些日子了一个新需求,需要在后台使用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 map = new HashMap();
        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;
    }

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

RestTemplate踩坑-乱码【不是中文乱码哦】_第1张图片
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之后的样子,大家再看一下。

RestTemplate踩坑-乱码【不是中文乱码哦】_第2张图片
image.png

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


image.png

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

RestTemplate踩坑-乱码【不是中文乱码哦】_第3张图片
image.png

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

一切都是巧合!

分享结束,谢谢观赏!

你可能感兴趣的:(RestTemplate踩坑-乱码【不是中文乱码哦】)