All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.jfinal.render.QrCodeRender Maven / Gradle / Ivy

Go to download

JFinal is a simple, light, rapid,independent, extensible Java WEB + ORM framework. The feature of JFinal looks like ruby on rails especially ActiveRecord.

The newest version!
package com.jfinal.render;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.jfinal.kit.StrKit;
import com.jfinal.render.Render;
import com.jfinal.render.RenderException;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * QrCodeRender 生成二维码
 */
public class QrCodeRender extends Render {

	private String content;
	private int width;
	private int height;
	private ErrorCorrectionLevel errorCorrectionLevel;

	/**
	 * 构造方法,经测试不指定纠错参数时,默认使用的是 'L' 最低级别纠错参数
	 * @param content 二维码携带内容
	 * @param width 二维码宽度
	 * @param height 二维码高度
	 */
	public QrCodeRender(String content, int width, int height) {
		init(content, width, height, null);
	}

	/**
	 * 带有纠错级别参数的构造方法,生成带有 logo 的二维码采用纠错原理
	 * 使用 ErrorCorrectionLevel.H 参数提升纠错能力
	 *
	 * ErrorCorrectionLevel 是枚举类型,纠错能力从高到低共有四个级别:
	 *  H = ~30% correction
	 *  Q = ~25% correction
	 *  M = ~15% correction
	 *  L = ~7%
	 *
	 *  使用的时候直接这样:ErrorCorrectionLevel.H
	 */
	public QrCodeRender(String content, int width, int height, ErrorCorrectionLevel errorCorrectionLevel) {
		init(content, width, height, errorCorrectionLevel);
	}

	/**
	 * 带有纠错级别参数的构造方法,纠错能力从高到低共有四个级别:'H'、'Q'、'M'、'L'
	 */
	public QrCodeRender(String content, int width, int height, char errorCorrectionLevel) {
		init(content, width, height, errorCorrectionLevel);
	}

	private void init(String content, int width, int height, char errorCorrectionLevel) {
		if (errorCorrectionLevel == 'H') {
			init(content, width, height, ErrorCorrectionLevel.H);
		} else if (errorCorrectionLevel == 'Q') {
			init(content, width, height, ErrorCorrectionLevel.Q);
		} else if (errorCorrectionLevel == 'M') {
			init(content, width, height, ErrorCorrectionLevel.M);
		} else if (errorCorrectionLevel == 'L') {
			init(content, width, height, ErrorCorrectionLevel.L);
		} else {
			throw new IllegalArgumentException("errorCorrectionLevel 纠错级别参数值,从高到低必须为: 'H'、'Q'、'M'、'L'");
		}
	}

	private void init(String content, int width, int height, ErrorCorrectionLevel errorCorrectionLevel) {
		if (StrKit.isBlank(content)) {
			throw new IllegalArgumentException("content 不能为空");
		}
		if (width < 0 || height < 0) {
			throw new IllegalArgumentException("width 与 height 不能小于 0");
		}
		this.content = content;
		this.width = width;
		this.height = height;
		this.errorCorrectionLevel = errorCorrectionLevel;
	}

	public void render() {
		response.setHeader("Pragma","no-cache");
		response.setHeader("Cache-Control","no-cache");
		response.setDateHeader("Expires", 0);
		response.setContentType("image/png");

		Map hints = new HashMap();
		hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
		hints.put(EncodeHintType.MARGIN, 0);    //去掉白色边框,极度重要,否则二维码周围的白边会很宽
		if (errorCorrectionLevel != null) {
			hints.put(EncodeHintType.ERROR_CORRECTION, errorCorrectionLevel);
		}

		try {
			// MultiFormatWriter 可支持多种格式的条形码,在此直接使用 QRCodeWriter,通过查看源码可知少创建一个对象
			// BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints);

			QRCodeWriter writer = new QRCodeWriter();
			BitMatrix bitMatrix = writer.encode(content, BarcodeFormat.QR_CODE, width, height, hints);

			// 经测试 200 X 200 大小的二维码使用 "png" 格式只有 412B,而 "jpg" 却达到 15KB
			MatrixToImageWriter.writeToStream(bitMatrix, "png", response.getOutputStream());    // format: "jpg"、"png"
		} catch (IOException e) {	// ClientAbortException、EofException 直接或间接继承自 IOException
			String name = e.getClass().getSimpleName();
        	if ("ClientAbortException".equals(name) || "EofException".equals(name)) {
        	} else {
        		throw new RenderException(e);
        	}
		} catch (Exception e) {
			throw new RenderException(e);
		}
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy