美文网首页
docker环境下tomcat容器生成中文名称文件乱码java

docker环境下tomcat容器生成中文名称文件乱码java

作者: sunland_0416 | 来源:发表于2020-11-26 14:07 被阅读0次

宿主机: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="[]|{}^&#x5c;&#x60;&quot;&lt;&gt;"
                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容器即可。

相关文章

网友评论

      本文标题:docker环境下tomcat容器生成中文名称文件乱码java

      本文链接:https://www.haomeiwen.com/subject/kefaiktx.html