使用docker过程中遇过的最诡异的问题,服务在本地环境中,通过在IDEA里面运行,或者使用java -jar ***.war运行,获取验证码图片都没有问题,但是运行在docker中,图片正常返回,但是上面的汉字却无法显示。
(正常返回)
(非正常返回)
将汉字写入图片的代码如:
private String drawRandomNum(Graphics2D g) {
StringBuffer sb = new StringBuffer();
// 设置颜色
g.setColor(Color.YELLOW);
// 设置字体
g.setFont(new Font("宋体", Font.ITALIC, 20));
// 准备常用汉字集
String base = "\u7684\u4e00\u4e86\u662f\u6211\u4e0d\u5728\u4eba\u4eec\u6709\u6765";
int x = 5;
// 控制字数
for (int i = 0; i < 4; i++) {
// 设置字体旋转角度
int degree = new Random().nextInt() % 30;
// 截取汉字
String ch = base.charAt(new Random().nextInt(base.length())) + "";
sb.append(ch);
// 正向角度
g.rotate(degree * Math.PI / 180, x, 20);
g.drawString(ch, x, 20);
// 反向角度
g.rotate(-degree * Math.PI / 180, x, 20);
x += 30;
}
System.out.println(sb.toString());
return sb.toString();
}
基本逻辑是从unicode编码的汉字字符集中随机抽取4个汉字,调用Graphics2D的drawString方法画入。
排查问题的第一步,将汉字字符集转化为英语字符集,方法调用没有问题,英语字母可以正常显示,问题似乎落在docker环境对中文字符的支持上。
通过参考,对container中locale进行检查和重置(修改container中locale的方法):
C.UTF-8本来就已经支持中文,所以问题也不在locale。
因为代码中使用了Graphics2D进行画图,试着用关键字”Graphics2D 画汉字 docker 乱码“百度一下,果然搜出了好东西。
问题的根源在于:container环境中缺乏对中文字体的支持,需要添加字体文件simsun.ttf 到/usr/share/fonts中,具体步骤如:
1)进入container:
docker exec -it 40ebba024c0b bash
2)打开/usr/share/fonts:
cd /usr/share/fonts
3)下载字体文件:
wget https://dlc2.pconline.com.cn/filedown_367689_7048847/3BswZ0YQ/simsun.zip
结果如:
4)解压simsun.zip:
unzip simsun.zip
结果如:
5)拷贝一份simsun.ttf,并重命名为simsun.tt
cp simsun.ttf simsun.tt
6)退出并重启container:
问题解决!!
结论:Docker环境和本地环境是存在差异的,在解决具体问题的过程中,需要将这种差异添加到打包的过程中,如本例中需要将字体文件进行拷贝,可以在Dockerfile中添加
COPY simsun.ttf /usr/share/fonts/simsun.tt
(由于使用了docker-maven-plugin进行打包,这一步并未实践)
来源:oschina
链接:https://my.oschina.net/u/4042451/blog/3041236