2018-05-29 这两天真的是被java服务器部署后的中文乱码折腾得吐血!

容器里部署了新的adn项目,结果报表的头部列名出现乱码。
出现乱码的是写在code里的中文列名。其他没有问题的中文列名来自之前打包的jar包中的字符串常量。
于是先修改code里的中文的各种表述吧。试过new String("平台".getBytes("UTF-8"),"ISO-8859-1"),各种组合都试过了,哪怕前后两个charset一样都试过了。还是乱码。
打印出来系统的file.encoding是UTF-8.
不断尝试,不断看不到希望——我已经被折磨死了。
能想到的都试过了,还是看不到结果。
我开始想为何jar包里的常量中文就不乱码?有什么特殊的?不可能有什么特殊的啊,运行时都跑在一个容器里呢?!
那么修改运行的容器的操作系统编码?于是Dockerfile中添加了ENV LANG="C.UTF-8",看过好几篇博客后实测才加的这一行。
结果还是不行啊?
见了鬼了,系统编码都修改了还不行?!
于是想只能再次打包jar包了,马上和之前打包的同事沟通下问问乱码问题。
聊着聊着,说到编译问题,猛然反应过来,编译环境是一个容器,它的默认LANG是POSIX,不支持中文,之前尝试LANG="C.UTF-8"去修改locale,但是失败了。正确的应该用export LANG="C.UTF-8"才会生效,但是当时已经被乱码气昏了头了,完全顾不上这个命令不生效。
仔细一想,编译绝对是问题。因为编译环境不支持中文,所以编译时存储的字节码肯定有问题,而jar包的区别就只在于它编译好了且存好了而且没有乱码——绝对是编译有效才能这样。
赶紧挂了电话,export LANG="UTF-8"修改编译环境的locale,然后code里的中文直接写原模原样的,编译保存,运行。
天哪,正常了!
苦苦折磨我两三天的中文乱码,竟然是这样被解决的,我心里都在流泪了...我的青春啊,我的烦恼啊...背后的原因竟然是我以前一直故意忽略容器的环境变量——不要去设置它,容器登录后终端下中文显示有问题也不用去管,程序没有乱码就行。结果用了这么久的编译环境,默认不支持中文我都忍受了这么久(前端一直默默地使用 var creativeName =encodeURI(decodeURI(encodeURI($.trim($("#creativeName").val())))); 这样的方式给我们传递中文)。

只要编译环境设置对了locale,(运行时环境当然我们现在也设置ENV了),不需要在code中对中文做任何特殊写法了。new String("平台".getBytes("UTF-8"),"ISO-8859-1")这种方式,测试发现,前后charset一样则没问题——但是ISO-8859-1不能用,可以用UTF-8和GBK。前后不一样一定乱码。这个方式的正确用法应该是使用byte传输,在一个地方getBytes(),另一个地方再还原(当然是用同样的charset),以后再也指望在同一个地方去用这个啦解决编码问题了。

注:在其中还发现一个老问题,dexec登录编译环境的容器中,locale是C.UTF-8,但是本地使用ssh连接到该容器中,locale就变成了POSIX。这个也算是起因之一了吧。之前在jumpserver管理的机器中就有类似问题。该怎么解决呢?

你可能感兴趣的:(2018-05-29 这两天真的是被java服务器部署后的中文乱码折腾得吐血!)