情景说明
项目集成了EMQX开源版,部署在windows server 2016上,出现了一个问题:
用户在界面输入的字符串,在代码里通过一定方法,发送到设备订阅的相应主题里面,设备端收到,会把utf-8格式转换为GB2312,然后根据文字,去中文字库芯片寻找文字,发送给语音模块,让语音驱动喇叭播报中文,LED点阵显示屏会把这些文字显示出来。
问题就出在中文上,设备转换不出来,换句话就是,系统发送出去的不是utf-8格式,奇怪的地方是,项目跑在Linux上没有问题,一切正常;在开发工具Eclipse或者Idea里也正常,偏偏挂到windows下,用cmd运行的时候,就不行了。而且系统都设置了编码utf-8了。
解决方案
先说解决方案。
1、服务器配置:jdk1.8,mysql5.7,EMQX 5.3.2,window server 2016,
2、cmd中输入 java -Dfile.encoding=UTF-8 -jar 你的jar包.jar
3、上面步骤,cmd会打印日志,应该也是乱码,原因是cmd的编码是默认gbk的,码值936。如果要正常显示,有两种途径,一是暂时修改cmd编码格式,一是永久修改(不推荐)。暂时修改输入代码chcp 65001即可。
解释说明
经过了解发现,项目需要三方面保持编码一致,才不会出现乱码问题
第一、源文件编码格式
第二、容器环境编码格式
第三、呈现文本内容的平台,如cmd,eclips的console等
一般乱码,主要是因为容器采用了不同的编码集。Linux默认是utf-8,而window 默认是GBK,虽然若依在源码里已经指定了utf-8,但那仅代表源文件编码,当项目跑在不同容器里,会调用容器编码解释运行,如果不一致,当然要出现乱码了。
另外为什么在开发工具里面没有这种现象?是因为此时项目跑起来调用的内置tomcat,项目里的aplication.yml已经指定内置tomcat编码为utf-8了,用utf-8编码去解读utf-8格式的源文件,当然是正确的不会乱码。
综上原因,在windows上运行时候,指定容器用utf-8编码格式,否则就用默认的GBK了
补充
当然还有一种解决方案是,直接在环境变量里指定jdk运行编码
变量名:JAVA_TOOL_OPTIONS
变量值:-Dfile.encoding=UTF-8
由于我们的服务器上,还有别人的项目也在跑,为了不影响他人,所以不采用这种方式了