一文教你解决生产环境中文乱码问题,亲测有效!!

前言

记录一下之前项目遇到的问题,相信应该也有不少童鞋遇到过,或者以后会遇到,描述如下

当时做了一个对图片添加水印的功能,这功能也上线了半个多月了,有天还没到公司的时候突然来个消息说水印信息显示不出来乱码,如下图所示↓

image.png

问题重现

我们本地来复现一下水印乱码的问题,如下

    public static void main(String[] args) {
        Color color=new Color(255,255,255,128);                               //水印图片色彩以及透明度
        // 原图位置, 输出图片位置, 水印文字颜色, 水印文字 C:\Users\LSH\Pictures
       new WaterMarkUtils().mark(new File("C:/Users/XXX/Pictures/IMG_1479.JPG"),"C:/Users/XXX/Pictures/IMG_1479.JPG", "C:/Users/XXX/Desktop/kdmt1.jpg",
               Color.red, "2020:09:14 21:38:18", "上海市上海市黄浦区");
    }
    
    .....
               // 加水印
            BufferedImage bufImg = new BufferedImage(srcImgWidth, srcImgHeight, BufferedImage.TYPE_INT_RGB);
            Graphics2D g = bufImg.createGraphics();
            g.drawImage(srcImg, 0, 0, srcImgWidth, srcImgHeight, null);
            // 设置字体
             Font font = new Font("Courier New", Font.PLAIN, 60);
            g.setColor(markContentColor); // 根据图片的背景设置水印颜色

            g.setFont(font);
    
复制代码

其中需要关注的就是设置字体的一行代码 Font font = new Font("Courier New", Font.PLAIN, 60); 设置水印显示的字体为Courier New,下面来看看水印显示效果↓:

image.png 显而易见中文字体还是乱码,反之如果设置为Font font = new Font("微软雅黑", Font.PLAIN, 60); 图片显示正常,看到这里想必大家也明白了。

本地环境我们使用 Courier New 字体乱码是因为本地(Windows)不存在该字体,使用微软雅黑未乱码则是因为本地环境存在该字体,故通过此可以排查到我们生产环境乱码的问题,因为生产环境中该字体系统中不存在

解决方案

  • 生产环境服务器中添加字体文件.ttc,读取字体文件.ttc
  • 项目resource中添加字体文件.ttc,读取static下的字体文件

先提供一个字体加载utils(省略部分代码)

public class SystemLoadFont {
    public static Font styleFont(String path,int style,float fontSize) {
        Assert.notNull(path);
        Font font = SystemLoadFont.loadStyleFont(path,style,fontSize);// 调用
        return font;
    }
public static Font loadStyleFont(String fontFileName,int style, float fontSize) {
            File file = new File(new String(fontFileName.getBytes("utf-8"), "utf-8"));
            if (!file.exists()) {
                //文件不存在
                return new java.awt.Font("XX", Font.PLAIN, 33);
            } else {
                //文件存在!
            }
            FileInputStream in = new FileInputStream(file);
            Font dynamicFont = Font.createFont(Font.TRUETYPE_FONT, in);
            Font dynamicFontPt =  dynamicFont.deriveFont(style,fontSize);
            in.close();
            return dynamicFontPt;
    }
}
复制代码

加载static下字体文件 String simsunPath = this.getClass().getClassLoader().getResource("simsun.ttc").getPath(); 替换 Font font = SystemLoadFont.styleFont(simsunPath,Font.PLAIN,60f); 再生成水印文件,如下:

image.png 读取服务器字体文件同理,替换路径则可,可通过配置路径的方式读取,更加灵活,通过这样的方式我们解决了乱码,这样也就不存在会因为该环境字体不存在而出现问题了。

字体文件可从网上下载,这里就不提供链接了,字体文件后缀为 xx.ttc

结尾

水文不易,多多点赞✌

猜你喜欢

转载自juejin.im/post/7039612125815242766