[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!

 

posted @ 2022-11-23 23:06  DavidHHuan  阅读(56)  评论(0编辑  收藏  举报