宿主机:SUSE Linux
宿主机loclae 显示zh_CN
宿主机上touch 中文文件名称可以正常在shell里显示
docker tomcat容器 locale zh_CN.gbk
docker容器内部touch 中文文件名称可以正常在shell里显示
但是通过servlet生成的中文文件名称显示乱码???
这个docker Tomcat的镜像是通过dockerfile构建的,以centos7为基础,复制了一个离线安装tomcat包
然后启动容器时候运行run.sh
#!/bin/bash
sh /usr/local/apache-tomcat-9.0.34/bin/startup.sh
tail -f /usr/local/apache-tomcat-9.0.34/logs/catalina.out
问题排查,首先查看tomcat配置是否有问题
tomcat conf server.xml 是否设置UTF-8
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
relaxedQueryChars="[]|{}^\`"<>"
maxThreads="1000"
URIEncoding="UTF-8" />
tomcat bin 启动文件catalina.sh
if [ -z "$LOGGING_MANAGER" ]; then
JAVA_OPTS="$JAVA_OPTS -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager "
else
JAVA_OPTS="$JAVA_OPTS $LOGGING_MANAGER"
fi
修改为以下:这里解决了catalina.out的乱码问题
if [ -z "$LOGGING_MANAGER" ]; then
JAVA_OPTS="$JAVA_OPTS -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Dfile.encoding=UTF8 -Dsun.jnu.encoding=UTF8"
else
JAVA_OPTS="$JAVA_OPTS $LOGGING_MANAGER -Dfile.encoding=UTF8 -Dsun.jnu.encoding=UTF8"
fi
docker 容器是否支持中文
docker exec -it tomcat bash
locale
里面已经改了,LANG=zh_CN.utf8,上面几个都不能解决。
没办法只能去java里面打印日志
import java. util.Properties;
import java.nio.charset.Charset;
....
Properties properties=System.getProperties();
System.out.prinln("编码"+properties.getProperty("file.encoding"));
System.out.prinln("编码"+properties.getProperty("sun.jnu.encoding"));
System.out.prinln(Charset.defaultCharset());
.....
发现,日志里面sun.jnu.encoding是ANSI_X3.4-1968;
file.encoding跟Charset.defaultCharset() 都是UTF-8
难怪会乱码,sun.jnu.encoding是会影响文件命名的,为啥这里不是UTF-8?
原来需要在catalina.sh里面配置。果断加入tomcat bin 启动文件catalina.sh上面几行
JAVA_OPTS="$JAVA_OPTS -Dsun.jnu.encoding=UTF8"
然后手动重启tomcat
cd /usr/local/apache-tomcat-9.0.34/bin
./shutdown.sh
./startup.sh
问题解决。
你以为完了?没有。。。
后面更改了web项目部分文件后重启容器发现问题依然出现。再次查看日志居然问题复现,这就奇怪了。为啥编码回去了?然后我又进入容器手动重启tomcat发现问题又解决了。那么现在明显是容器启动过程中的问题了。
为了验证我的想法,我在run.sh里添加了日志
#!/bin/bash
locale>>/home/locale.log
sh /usr/local/apache-tomcat-9.0.34/bin/startup.sh
tail -f /usr/local/apache-tomcat-9.0.34/logs/catalina.out
重启容器后发现locale.log内容是
LANG=
LC_CTYPE="POSIX"
LC_NUMERIC="POSIX"
LC_TIME="POSIX"
LC_COLLATE="POSIX"
LC_MONETARY="POSIX"
LC_MESSAGES="POSIX"
LC_PAPER="POSIX"
LC_NAME="POSIX"
LC_ADDRESS="POSIX"
LC_TELEPHONE="POSIX"
LC_MEASUREMENT="POSIX"
LC_IDENTIFICATION="POSIX"
LC_ALL=
这就是了,启动docker容器的时候顺带启动了Tomcat,但是启动Tomcat的时候环境居然是不支持中文的POSIX.
既然知道问题原因,那么就好解决了。一种方法是重新打镜像,把LANG=zh_CN添加到dockerfile里的ENV里。
我这里尝试了另外一种懒方法,在run.sh里启动Tomcat命令前重新设置一下LANG
#!/bin/bash
locale>>/home/locale.log
LANG=zh_CN
source /etc/profile
locale>>/home/locale.log
sh /usr/local/apache-tomcat-9.0.34/bin/startup.sh
tail -f /usr/local/apache-tomcat-9.0.34/logs/catalina.out
再次查看locale.log发现问题解决。程序运行也没问题。不用每次重启tomcat时候进入容器内部了,直接重启docker容器即可。