[Java] 操作系统字符集引发的血泪排查
关键字: java, springboot, springcloud, k8s, docket
最近由于某些原因,需要把全部java系统,从A云商迁移到B云商。
前面的部署迁移过程也挺辛苦的,就不说了,好不容易把整套spring cloud重新搭建起来,也能正常运行了。
好,开始测试!
尝试请求某个系统的登录接口
What?为什么会用户不存在呢?数据库没动过呀,自己写SQL去查用户也是存在的!
好,查日志!
嗯?怎么loginName全是问题来的?注:登录名是中文来的。对,首先想到的可能是不是数据传输的时候字符集有问题。
于是,手动把数据库的用户名改成英文的。果然,用英文登录成功了!但靠改用户名为英文并不是解决问题的方法,于是,又把用户名在数据库里面改回中文
好,开始排查了。中间花了各种手段,打了很多日志,最终开始通过这段代码发现了端倪
注意body的输出,还是乱码的!
于是想到了是不是字节流有问题,
看下面的输出
现在可以百分百的确认,就是字符集的问题了!!!
但为什么jvm读到的字符集不对呢?这个时候,首先想到的是,去设置java启动参数,增加
-Dfile.encoding=UTF-8
再次尝试中文名登录,成功了!
但通过强行加启动参数为utf-8总感觉怪怪的,再google了一下,都是说,如果不设置启动参数,默认java是以操作系统字符集为准的。
对,这个时候,看下操作系统的字符集
对!问题就是,操作系统的$LANG变量,没有值!
最终问题已经定位到的,只要设置好$LANG这个变量为utf-8就可以了,不需要加java的启动参数!
echo 'LANG="zh_CN.UTF-8"' > /etc/locale.conf source /etc/locale.conf
完美解决!!!
Have fun with Java!