Java使用com.google.zxing生成二维码在Linux环境中无法生成二维码问题

二维码在我们的日常生活中已经泛滥了,所以作为死开发的我也没能逃过给用户创建二维码这个功能的实现。好在轮子已经有大佬造好了。
我的环境是:
Spring boot项目
CentOS 7.4
Tomcat 8

代码实现:

import java.awt.Color;

public class MatrixToLogoImageConfig {
    //logo默认边框颜色
    public static final Color DEFAULT_BORDERCOLOR = Color.RED;
    //logo默认边框宽度
    public static final int DEFAULT_BORDER = 2;
    //logo大小默认为照片的1/5
    public static final int DEFAULT_LOGOPART = 5;

    private final Color borderColor;
    private final int logoPart;

    /**
     * Creates a default config with on color and off color
     * generating normal black-on-white barcodes.
     */
    public MatrixToLogoImageConfig() {
        this(DEFAULT_BORDERCOLOR, DEFAULT_LOGOPART);
    }


    public MatrixToLogoImageConfig(Color borderColor, int logoPart) {
        this.borderColor = borderColor;
        this.logoPart = logoPart;
    }


    public Color getBorderColor() {
        return borderColor;
    }


    public int getBorder() {
        return DEFAULT_BORDER;
    }


    public int getLogoPart() {
        return logoPart;
    }
}
import java.awt.BasicStroke;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Hashtable;

import javax.imageio.ImageIO;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageConfig;
import com.google.zxing.client.j2se.MatrixToImageWriter;

import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

public class MatrixToImageWriterEx {

    private static final MatrixToLogoImageConfig DEFAULT_CONFIG = new MatrixToLogoImageConfig();

    /**
     * 根据内容生成二维码数据
     * @param content 二维码文字内容[为了信息安全性,一般都要先进行数据加密]
     * @param width 二维码照片宽度
     * @param height 二维码照片高度
     * @param filePath 文件路径,带文件名,.png或.jpg后缀
     */
    public static boolean createQRCode(String content, int width, int height, String filePath){

        // 判断后缀
        String format = filePath.substring(filePath.length()-4);
        if (!format.equals(".jpg")) {
            if (!format.equals(".png")) {
                return false;
            }
        }

        Hashtable<EncodeHintType, Object> hints = new Hashtable<>();
        //设置字符编码
        hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
        // 指定纠错等级
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
        BitMatrix matrix = null;
        try {
            matrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints);
            MatrixToImageWriter.writeToFile(matrix, format.substring(format.length()-3), new File(filePath), new MatrixToImageConfig());
        } catch (WriterException|IOException e) {
            e.printStackTrace();
        }
        return true;
    }

    /**
     * 写入二维码、以及将照片logo写入二维码中
     * @param matrix 要写入的二维码
     * @param format 二维码照片格式
     * @param imagePath 二维码照片保存路径
     * @param logoPath logo路径
     * @param logoConfig logo配置对象
     */
    public static void writeToFile(BitMatrix matrix, String format, String imagePath, String logoPath, MatrixToLogoImageConfig logoConfig) throws IOException {
        MatrixToImageWriter.writeToFile(matrix, format, new File(imagePath), new MatrixToImageConfig());

        //添加logo图片, 此处一定需要重新进行读取,而不能直接使用二维码的BufferedImage 对象
        BufferedImage img = ImageIO.read(new File(imagePath));
        MatrixToImageWriterEx.overlapImage(img, format, imagePath, logoPath, logoConfig);
    }

    /**
     * 将照片logo添加到二维码中间
     * @param image 生成的二维码照片对象
     * @param imagePath 照片保存路径
     * @param logoPath logo照片路径
     * @param formate 照片格式
     */
    public static void overlapImage(BufferedImage image, String formate, String imagePath, String logoPath, MatrixToLogoImageConfig logoConfig) {
        try {

            if (logoPath != null) {
                Graphics2D g = image.createGraphics();
                BufferedImage logo = ImageIO.read(new File(logoPath));
                //考虑到logo照片贴到二维码中,建议大小不要超过二维码的1/5;
                int width = image.getWidth() / logoConfig.getLogoPart();
                int height = image.getHeight() / logoConfig.getLogoPart();
                //logo起始位置,此目的是为logo居中显示
                int x = (image.getWidth() - width) / 2;
                int y = (image.getHeight() - height) / 2;
                //绘制图
                g.drawImage(logo, x, y, width, height, null);

                //给logo画边框
                //构造一个具有指定线条宽度以及 cap 和 join 风格的默认值的实心 BasicStroke
                g.setStroke(new BasicStroke(logoConfig.getBorder()));
                g.setColor(logoConfig.getBorderColor());
                g.drawRect(x, y, width, height);
                g.dispose();
            }


            //写入logo照片到二维码
            ImageIO.write(image, formate, new File(imagePath));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

    public static void main(String[] a) throws Exception{
        boolean s = createQRCode("https://www.baidu.com/", 512, 512, "/home/key/erweima/iiiooop.png");
        System.out.println(s);
    }

方法的调用这里就不贴出来了。
功能完成后,在我的开发环境中Win10+Tomcat 8,都是正常的,简直完美。然后丢到测试环境(CentOS 7.4 + Tomcat 8)就完蛋了,无法生成二维码。
然后查了一些网上的资料:
https://blog.csdn.net/lxltmac/article/details/86693392

linux系统图形控件未启动导致的。
这时需要在tomcat目录下的bin/catalina.sh文件的对于地方加入-Djava.awt.headless=true /
在Linux服务器上搜索$JAVA_OPTS然后找到八处跟下面类似一样的地方加上上面这个参数配置,如:
exec “$_RUNJDB” “$LOGGING_CONFIG” $LOGGING_MANAGER $JAVA_OPTS $CATALINA_OPTS
-Djava.endorsed.dirs="$JAVA_ENDORSED_DIRS" -classpath “$CLASSPATH”
-sourcepath “$CATALINA_HOME”/…/…/java
-Djava.security.manager
-Djava.security.policy=="$CATALINA_BASE"/conf/catalina.policy
-Dcatalina.base="$CATALINA_BASE"
-Dcatalina.home="$CATALINA_HOME"
-Djava.awt.headless=true \
-Djava.io.tmpdir="$CATALINA_TMPDIR"
org.apache.catalina.startup.Bootstrap “$@” start

我在我的tomcat中确实找到8个这种样子的位置,依次添加“-Djava.awt.headless=true \”,重启Tomcat:
报错了:

Cannot find ./catalina.sh
The file is absent or does not have execute permission
This file is needed to run this program

因为我是将这个文件下载到本地再修改的,修改完成再上传到服务器上,造成了没有读写权限,解决:
在tomcat的bin目录下执行:

chmod +x *.sh

然后重启tomcat成功,但是还是无法生成二维码,也可能tomcat对我要存放二维码那个文件夹没有读写权限,然后我将存放二维码的文件夹换到/home目录下,问题解决了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章