由于业务拓展,新买了台系统为centOS7的服务器,配置完jdk和nginx之后,将服务发布到服务器上并部署启动,然后刷新页面,神奇的事情就出现了:
第一个想到的问题,就是进行本地调试,发现一切正常;于是在生成验证码文本的地方加上了logger输出,再次发布程序到服务器上,确定是否是文本生成时产生的问题,附上代码:
// String vcode = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
String vcode = "0123456789";
codeImg = new BufferedImage(74, 30, BufferedImage.TYPE_3BYTE_BGR);
Graphics2D g = codeImg.createGraphics();
g.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setColor(Color.white);
g.fillRect(0, 0, 74, 30);
for (int i = 0; i < 100; i++) {
int x = (int) Math.round((Math.random() * 74));
int y = (int) Math.round((Math.random() * 30));
Color color = new Color((float) (Math.random() * 0.7) + 0.3F, (float) (Math.random() * 0.7) + 0.3F,
(float) (Math.random() * 0.7) + 0.3F);
g.setColor(color);
g.drawRect(x, y, 1, 1);
}
code = "";
for (int i = 0; i < 4; i++) {
int fontsize = (int) Math.round(Math.random() * 3 + 20);
Font font = new Font("", (int) Math.round(Math.random() * 3), fontsize);
Color color = new Color((float) (Math.random() * 0.7), (float) (Math.random() * 0.7), (float) (Math.random() * 0.7));
g.setColor(color);
g.setFont(font);
// Character c = vcode.charAt(Math.round((float) Math.random() * 35));
Character c = vcode.charAt(Math.round((float) Math.random() * 9));
code += c;
g.drawString(c + "", 18 * i + (int) (Math.random() * 10 - 5) + 2, 24 + (int) (Math.random() * 10 - 5));
}
logger.info("code:{}",code);
}
运行服务之后,通过日志,发现文本生成输出正常,开始怀疑是否是jdk版本不一致导致的问题。因为我们开发环境装的是jdk7,服务器上装的是jdk8,难道是jdk做向下兼容的时候出现的问题;于是将项目发到另一台也是jdk8的服务器上,启动测试,发现一切正常,排除jdk版本问题。此时,再次查看代码,发现Graphics2D在生成文本的时候,其实调用了Font组件
进入font源码:
public Font(String name, int style, int size) {
this.name = (name != null) ? name : "Default";
this.style = (style & ~0x03) == 0 ? style : 0;
this.size = size;
this.pointSize = size;
}
发现用的是系统的默认字体,windows平台默认是微软雅黑,查看对应服务器上的系统字体:
以及系统的字体列表:
发现并没有我们需要的字体,于是基本可以确定问题点是出在系统字体上面。
解决方法很直接,就是直接到windows的字体目录下
选择 微软雅黑 字体,直接上传到服务器的字体文件目录下( /usr/share/fonts/),可以创建自定义目录:(我是新建了micro的目录,将拷贝出来的字体放在了此目录下)
然后利用命令:fc-cache 重新载入字体配置(该步骤一定得操作否则验证码还是乱码),清除字体缓存。然后重启项目,发现验证码正常。
由于自己也遇到了类似的问题,遂转载记录下。
转自:https://blog.csdn.net/zs296332478/article/details/78144460