应用系统在linux服务器上部署启动,然后刷新页面,验证码图形出现乱码:
附上代码:
// 设置页面不缓存response.setHeader("Pragma", "No-cache");response.setHeader("Cache-Control", "no-cache");response.setDateHeader("Expires", 0);// response.setContentType("image/png");// 在内存中创建图象final BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);// 获取图形上下文final Graphics2D graphics = (Graphics2D) image.getGraphics();// 设定背景颜色graphics.setColor(Color.WHITE); // ---1graphics.fillRect(0, 0, width, height);// 设定边框颜色//graphics.setColor(getRandColor(100, 200)); // ---2graphics.drawRect(0, 0, width - 1, height - 1);final Random random = new Random();// 随机产生干扰线,使图象中的认证码不易被其它程序探测到for (int i = 0; i < count; i++) {graphics.setColor(getRandColor(150, 200)); // ---3final int x = random.nextInt(width - lineWidth - 1) + 1; // 保证画在边框之内final int y = random.nextInt(height - lineWidth - 1) + 1;final int xl = random.nextInt(lineWidth);final int yl = random.nextInt(lineWidth);graphics.drawLine(x, y, x + xl, y + yl);}// 取随机产生的认证码(4位数字)final String resultCode = exctractRandCode();for (int i = 0; i < resultCode.length(); i++) {// 将认证码显示到图象中,调用函数出来的颜色相同,可能是因为种子太接近,所以只能直接生成// graphics.setColor(new Color(20 + random.nextInt(130), 20 + random// .nextInt(130), 20 + random.nextInt(130)));// 设置字体颜色graphics.setColor(Color.BLACK);// 设置字体样式//graphics.setFont(new Font("Arial Black", Font.ITALIC, 18));graphics.setFont(new Font("Times New Roman", Font.BOLD, 24));// 设置字符,字符间距,上边距graphics.drawString(String.valueOf(resultCode.charAt(i)), (23 * i) + 8, 26);}// 将认证码存入SESSIONrequest.getSession().setAttribute(SESSION_KEY_OF_RAND_CODE, resultCode);// 图象生效graphics.dispose();// 输出图象到页面ImageIO.write(image, "JPEG", response.getOutputStream());
运行服务之后,通过日志,发现验证码生成输出正常。查看代码,发现Graphics2D在生成文本的时候,其实调用了Font组件
进入font源码:
系统代码中使用的字体是“Times New Roman”,本地测试验证码图片没问题,是因为window平台是有该字体的,查看对应服务器上的系统字体:
以及系统的字体列表:
发现并没有我们需要的字体,于是基本可以确定问题点是出在系统字体上面。
解决方法很直接,就是直接到windows的字体目录下
选择该字体,直接上传到服务器的字体文件目录下,可以创建自定义目录:(我是新建了Times New Roman的目录,将拷贝出来的字体放在了此目录下)
然后利用命令:fc-cache 重新载入字体配置,清除字体缓存。然后重启项目,发现一切ok。