Skip to content

Commit

Permalink
servlet to generate QRcode png according to chart.googleapis.com/chart
Browse files Browse the repository at this point in the history
  • Loading branch information
rkrenn committed Apr 14, 2024
1 parent 9861e9f commit 260c991
Show file tree
Hide file tree
Showing 4 changed files with 134 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,8 @@ public final void remove() {
private static final String HEX_DIGITS = "0123456789ABCDEF";
public final static String GIF_FILENAME_EXTENSION = "gif";
public static final String GIF_MIMETYPE_STRING = "image/gif";
public static final String PNG_FILENAME_EXTENSION = "png";
public static final String PNG_MIMETYPE_STRING = "image/png";
public static final String HTML_MIMETYPE_STRING = "text/html";
public static final String BEACON_PATH = "beacon";
public static final String UNSUBSCRIBE_PATH = "unsubscribe";
Expand Down
119 changes: 119 additions & 0 deletions web/src/main/java/org/phoenixctms/ctsms/web/servlet/QRCodeServlet.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
package org.phoenixctms.ctsms.web.servlet;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Hashtable;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.phoenixctms.ctsms.util.CommonUtil;
import org.phoenixctms.ctsms.web.util.GetParamNames;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

public class QRCodeServlet extends FileServletBase {

private final static ErrorCorrectionLevel DEFAULT_ERROR_CORRECTION_LEVEL = ErrorCorrectionLevel.L;
private final static int DEFAULT_WIDTH = 100;
private final static int DEFAULT_HEIGHT = 100;
private final static int DEFAULT_MARGIN = 4;
private final static String FILE_NAME = "qrcode." + CommonUtil.PNG_FILENAME_EXTENSION;

@Override
protected FileStream createFileStream(HttpServletRequest request, HttpServletResponse response) throws IOException {
ErrorCorrectionLevel errorCorrectionLevel = DEFAULT_ERROR_CORRECTION_LEVEL;
int margin = DEFAULT_MARGIN;
try {
String labelData[] = request.getParameter(GetParamNames.QR_CODE_CHLD.toString()).trim().split("\\s*\\|\\s*", 2);
errorCorrectionLevel = ErrorCorrectionLevel.valueOf(labelData[0]);
margin = Integer.parseInt(labelData[1]);
} catch (Exception e) {
}
int width = DEFAULT_WIDTH;
int height = DEFAULT_HEIGHT;
try {
String size[] = request.getParameter(GetParamNames.QR_CODE_CHS.toString()).trim().split("\\s*x\\s*", 2);
width = Integer.parseInt(size[0]);
height = Integer.parseInt(size[1]);
} catch (Exception e) {
}
String text = request.getParameter(GetParamNames.QR_CODE_CHL.toString());
final byte[] data;
final Long fileSize;
if (!CommonUtil.isEmptyString(text)) {
Hashtable<EncodeHintType, Object> hintMap = new Hashtable<>();
//hintMap.put(EncodeHintType.CHARACTER_SET, "UTF-8");
hintMap.put(EncodeHintType.ERROR_CORRECTION, errorCorrectionLevel);
hintMap.put(EncodeHintType.MARGIN, margin);
QRCodeWriter qrCodeWriter = new QRCodeWriter();
BitMatrix byteMatrix = null;
try {
byteMatrix = qrCodeWriter.encode(text, BarcodeFormat.QR_CODE, width, height, hintMap);
} catch (Exception e) {
}
if (byteMatrix != null) {
BufferedImage image = new BufferedImage(byteMatrix.getWidth(), byteMatrix.getHeight(), BufferedImage.TYPE_INT_RGB);
image.createGraphics();
Graphics2D graphics = (Graphics2D) image.getGraphics();
graphics.setColor(Color.WHITE);
graphics.fillRect(0, 0, byteMatrix.getWidth(), byteMatrix.getHeight());
graphics.setColor(Color.BLACK);
for (int i = 0; i < byteMatrix.getWidth(); i++) {
for (int j = 0; j < byteMatrix.getHeight(); j++) {
if (byteMatrix.get(i, j)) {
graphics.fillRect(i, j, 1, 1);
}
}
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(image, CommonUtil.PNG_FILENAME_EXTENSION, baos);
data = baos.toByteArray();
fileSize = (long) data.length;
} else {
data = null;
fileSize = null;
}
} else {
data = null;
fileSize = null;
}
return new FileStream() {

@Override
public String getFileName() {
return FILE_NAME;
}

@Override
public Long getFileSize() {
return fileSize;
}

@Override
public String getMimeType() {
return CommonUtil.PNG_MIMETYPE_STRING;
}

@Override
public InputStream getStream() {
return new ByteArrayInputStream(data);
}

@Override
public boolean isNotFound() {
return data == null;
}
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,10 @@ public enum GetParamNames {
REFERER("referer"),
UUID("uuid"),
VALIDATE("validate"),
BEACON("beacon");
BEACON("beacon"),
QR_CODE_CHLD("chld"),
QR_CODE_CHS("chs"),
QR_CODE_CHL("chl");

private final String value;

Expand Down
9 changes: 9 additions & 0 deletions web/src/main/webapp/WEB-INF/web.xml
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,11 @@
<servlet-class>org.phoenixctms.ctsms.web.servlet.UnsubscribeServlet</servlet-class>
<load-on-startup>3</load-on-startup>
</servlet>
<servlet>
<servlet-name>qrCodeServlet</servlet-name>
<servlet-class>org.phoenixctms.ctsms.web.servlet.QRCodeServlet</servlet-class>
<load-on-startup>4</load-on-startup>
</servlet>
<!-- overlapping mappings -->
<!-- http://www.roguewave.com/portals/0/products/hydraexpress/docs/3.5.0/html/rwsfservletug/4-3.html -->
<servlet-mapping>
Expand All @@ -180,6 +185,10 @@
<servlet-name>unsubscribeServlet</servlet-name>
<url-pattern>/unsubscribe/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>qrCodeServlet</servlet-name>
<url-pattern>/chart</url-pattern>
</servlet-mapping>
<context-param>
<param-name>javax.faces.VALIDATE_EMPTY_FIELDS</param-name>
<param-value>true</param-value>
Expand Down

0 comments on commit 260c991

Please sign in to comment.