记一次乱码的排查

         最近参与公司移动端的开发,后台用pc端的服务,前端用公司封装的tinyBuild开发,相当于h5嵌入方式开发移动App,一套类h5的代码可以生成安卓和ios两个平台的应用。

         首先交代一下背景,后台代码以xml报文格式返回,前端接收后将xml报文转成json来读取数据。Servlet中设置的字符集为UTF-8,前端也设置了字符集为UTF-8,如下图所示:

         这样的背景下,在安卓端一直运行都没有问题,但是ios端的中文都乱码了,于是就有了下面的过程。

  1. 初步猜测前端的这条js对ios无效,后找研发tinyBuild的同事证实是有效的,排除。
  2. 查看系统JVM参数-Dfile.encoding=UTF-8,没有问题。于是尝试修改jvm参数为GBK,-Dfile.encoding=GBK,看看有什么效果,并从中看看能不能有什么收获。(这种通过逆向思维和踩雷的方式排查问题的思路我不知道叫什么名字,但是应该是一种比较科学的方式)。这时候,idea控制台中的日志中的中文也乱码了,但是有一个发现,相同中文的乱码和ios端显示的乱码一致,说明ios端是用GBK去解码了,这是一个重大收获。
  3. 将jvm参数改回去,继续排查原因。通过前端日志发现,后台返回到前端的xml报文中的中文是正常的,但是转成json之后显示就乱码了,定位到问题发生的具体位置,于是着重关注转json的这个方法xmlToJson()。该方法为tinyBuild封装的方法,无法查看具体实现。这时候就我想到能否自己重写一个js方法来解析xml报文,将其转换成json。但是由于tinyBuild里面只支持原生js,这个方法实现起来可能有一定困难,暂时先不考虑,作为备用选项。
  4. 但是这个方法其他团队也有在用,为什么没有问题了,为了确定是否为这个方法的问题,我自定义了一段含有中文的xml,<abc>这是中文</abc>,通过这个方法来转换成json,发现可以成功转换,没有问题。这下问题到了死胡同,感觉前面的推断都是错误的,整个方向都错了。
  5. 一时之间找不到方向,于是向tinyBuild的研发团队求助,想看看能不能查到这个方法的具体实现,然而并没有一个非常清楚这件事的同事,但是他们给了一个方向,有另一个团队也在用tinyBuild开发,用且后台字符集也是utf-8,但是前端中文能正常显示。
  6. 于是找了另一个团队,请他们提供了一段有中文的返回报文,然后用该方法转json,发现中文没有乱码!!!于是仔细对比我们的报文和他们的报文,发现报文头<?xml version="1.0" encoding="UTF-8"?>中的encoding不同,他们的是utf-8,我们的是gbk。这算是解决问题的关键线索了。
  7. 于是想到让后台返回报文头为UTF-8的报文,发现后台框架封装得有点复杂,一时半会找不到代码的具体位置,同时也考虑到pc端也在用这个后台,修改之后,pc端会不会出现乱码,有点不敢乱动。
  8. 最后思来想去,想到xmlToJson之前在js里面拿到的其实只是一个xml报文的字符串,既然是字符串,那是不是可以直接通过replace()方法修改其中的内容呢,实践出真知,直接在转换之前加上这样一行代码。

  1. 测试通过,问题解决。

总结,虽然解决问题的办法不是非常优雅,但是绝对算是非常简单的。《大型网站技术架构》作者李智慧在该书中写道“解决问题的方法都是简单的”,我非常认同这句话,技术是用来解决问题的,不是用来增加问题的,如果你解决一个问题的方法过于复杂,那你可能需要考虑一下思路是否正确,而且你这种做法除了会增加维护成本之外,是否还会带来一些其他没有考虑到的问题,而且这个问题其他同事排查起来是否会非常困难。

最后,我自己也有一句话想说,技术让我们解决问题多了一种方法,不是让我们解决问题只剩下技术这一种方法。

猜你喜欢

转载自blog.csdn.net/u012804886/article/details/81261498