跨服务中文传输乱码问题总结

1.问题背景

    最近在做内部系统与银行对接的支付网关,其中涉及到跨服务的编码转换问题。

    这次遇到的是UTF-8(我们使用的编码)与GBK(某银行使用的编码)的中文传输乱码问题。

    刚开始解决乱码问题的时候,心想解决方式无非是:按照编码的格式进行转码。

    经过这次问题,对乱码问题有了进一步的认识,原来乱码不仅仅是转入转出格式统一,还涉及到系统编码、IDE工具、tomcat服务等等网络传输带来的问题。

 

2.解决尝试

主要从系统内UTF-8GBK输出、接收系统外传输的GBK数据(输入、输出)两方面考试。

    1)系统内UTF-8GBK

  • 使用URLEncoder.encode传输数据,使用时进行decoder

    String plainData = java.net.URLEncoder.encode(plainDataR.trim(),"GBK");

    java.net.URLDecoder.decode(plainData, "GBK"));

  • 页面传输设置编码GBK

    <%@ page contentType="text/html; charset=GBK" session="false" %>

 

    2)接收系统外传输的GBK数据

  • 使用string.getBytes()进行转码,需要指定编码格式

        string.getBytes()不指定编码将使用系统默认编码或者IDE默认编码进行编译。

        String本身没有编码格式,需要指定编码,如果不指定,就会默认使用系统编码。

 

  • 添加filter进行编码设置

    获取请求编码,判断若是GBK,将request设置为GBK编码

    if("GBK".equals(request.getCharacterEncoding())){

        request.setCharacterEncoding(request.getCharacterEncoding());

        log.info("====filter======plain="+request.getParameter("Plain"));

    }

    备注:

    注意struts.xml的配置

        1.使用StrutsPrepareFilter及StrutsExecuteFilter

       添加charsetFilter不生效,最后查明原因是struts2默认编码为UTF-8,经过         StrutsPrepareFilter已将请求过滤成UTF-8编码,再执行charsetFilter已不生效。

        在StrutsPrepareFilter和StrutsExecuteFilter之间添加自定义filter.

        2)  修改为先执行自定义charsetFilter,再使用FilterDispatcher即可生效。

  •   修改tomcat ,取消默认编码设置,增加useBodyEncodingForURI="true"

      URIEncoding="UTF-8" 

           useBodyEncodingForURI="true"


3.问题总结

设置eclipse默认编码为UTF-8java文件采用UTF-8编码格式进行编译。银行jar包为GBK编码编译,传递GBK编码,调用银行签名算法,报验签失败,最终查看银行jar包代码,问题归根于string.getBytes(),未设置编码格式,采用系统默认编码UTF-8,所以导致验签失败。


最终去掉其他尝试方法,将jar包里签名算法修改为string.getBytes(GBK)解决问题。

猜你喜欢

转载自yuyajian.iteye.com/blog/2144827
今日推荐