docker中部署的应用,获取含有中文字符的验证码图片时无法正常显示

一个人想着一个人 提交于 2019-12-09 17:25:54

使用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进行打包,这一步并未实践)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!