宿主機: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容器即可。