数据在java工程中乱码_java项目乱码问题解决方案

上周在微信项目中出现一个比较棘手的乱码问题,有一些解决心得跟大家分享:

一、问题

首先肯定了几个事实:

0、在/etc/sysconfig/i18n文件中设置linux系统编码格式:LANG=en_US.UTF-8

1、  微信关注回消息,格式肯定是UTF-8。

2、  微信项目编码格式是UTF-8

3、  项目的过滤器、拦截器等都设置为UTF-8

4、  在response对象返回时,设置了编码格式为UTF-8,即:response.setCharacterEncoding(“UTF-8”);

5、  在web工程向biz工程写入数据流时,也设置了UTF-8,即:BufferedWriter out = newBufferedWriter(new OutputStreamWriter(httpURLConnection.getOutputStream(),"UTF-8"));

6、  biz工程在读取数据流时也设置了UTF-8,即:BufferedReaderbr = new BufferedReader(new InputStreamReader((ServletInputStream)request.getInputStream(), "UTF-8"));

……

问题出来了,即便做了上述设置,写入到数据库依然是乱码,于是开始怀疑是数据库编码格式不对,经查,发现SQL Server确实不支持UTF-8的数据,查看SQLServer的方式如下:

SELECT COLLATIONPROPERTY('Chinese_PRC_Stroke_CI_AI_KS_WS', 'CodePage')

936 简体中文GBK

950 繁体中文BIG5

437 美国/加拿大英语

932 日文

949 韩文

866 俄文

65001 unicode UFT-8

查出来是“936”,说明SQLServer确实是GBK格式。

那怎么才能解决呢?

二、解决方案

1、尝试转码

最开始很想当然地是将UTF-8转码为GBK,通过语句:newString(str.getBytes("GBK"), "UTF-8");

结果失败!

2、尝试以GBK写入数据流,再以GBK读出数据流

结果失败!

3、通过中间格式ISO-8859-1过渡转换

结果失败!

4、修改数据库驱动的编码格式:

DBUrl=jdbc:sqlserver://10.140.129.11:64013;useUnicode=true&characterEncoding=GBK;DatabaseName=wxtest

网上提示这是个很重要的原因,具体参见:

但如此配置后,仍然不能奏效,这是我不得不重新考虑问题的根本原因,是否在系统层面出了问题。

5、使用locale命令查看系统语言环境变量,发现环境变量又变回了zh_CN.GB2312,于是深究其原因,发现了如下线索:

原来,linux设置语言环境变量时,有多个参数可以设置:LANG,LC_*,LC_ALL,且其优先级顺序为:

LC_ALL > LC_* >LANG

因此设置了LANG变量还不够,可能会被LC_ALL覆盖掉,也就是说虽然看起来是在UTF-8环境中运行,但实际上还是运行在在GBK环境!!因此在/etc/sysconfig/i18n文件中设置了LC_ALL= en_US.UTF-8(注意设置完成后要重启)。

6、  Unicode转码

因为我们在第4条中设置了userUnicode=true,JAVA虚拟机都是以unicode的方式在内存中运行,因此在写入对象中调用了Unicode2GBK的方法转码,然后写入到数据库,一切正常!具体方法参见:

以上是解决乱码的全过程,可能有些方案还没测试到(如同时去掉unicode连接和unicode转码),但我们日常项目中遇到的乱码问题,不外乎上述涉及的内容,以此分享之,希望能对大家有所帮助。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值