JSP サイトを管理している知り合いが「QRCode を表示したい」と言っていたので、週末にちょっと試してみました。
Java だと OSS (Apache License 2.0) の ZXing がよく使われているみたいなので、JSP Web サイトに組み込んだメモとなります。
実際の Web 画面
以下のような入力画面で QRCode に指定したいURLを入力して「Submit」すると
以下のように URL を QRCode に変換して表示します。「Back」で元ページに戻ります。
開発環境
今回利用した開発環境は素の Eclipse 2020-09 (4.17.0) の Java EE パースペクティブで、サーバーに Tomcat v8.5 を追加指定したものです.
赤枠が今回のために追加、作成したファイルになります。
WebContent/WEB-INF/lib
には関連する jar ファイルをコピーしてあります。
ZXing リポジトリに jar が見当たらないので、MVN Repository の ZXing Core や ZXing Java SE Extensions などから入手すると良いでしょう。
jaxb-api-2.3.1.jar
は Java8 などの環境では必要ないかもしれません。エラーが出るようでしたら、やはり MVN Repository の JAXB API などから入手して配置してください。
実際のコード
入力ページ
入力ページは通常の html ページです。Bootstrap のテンプレート にフォーム要素を追加しただけの、非常にシンプルなものです。
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous">
<title>Simple QR sample with JSP</title>
</head>
<body>
<div class="container">
<h2>Simple QR sample with JSP</h2>
<form action="/test01/QRCode.jsp"> <!-- 遷移先の JSP ページ -->
<div class="form-group">
<label for="i_url">Target URL</label>
<input type="text" class="form-control" id="i_url" name="i_url">
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js" integrity="sha384-B4gt1jrGC7Jh4AgTPSdUtOBvfO8shuf57BaghqFfPlYxofvL8/KUEfYiJOMMV+rV" crossorigin="anonymous"></script>
</body>
</html>
JSP ページ
さてこちらは、入力を受けて QRCode を生成している部分です。ZXing のサンプルを、そのまま JSP 化したので、素直なコードだと思います。
<%@ page import="com.google.zxing.qrcode.QRCodeWriter" %>
<%@ page import="com.google.zxing.common.BitMatrix" %>
<%@ page import="com.google.zxing.BarcodeFormat" %>
<%@ page import="com.google.zxing.client.j2se.MatrixToImageWriter" %>
<%@ page import="java.awt.image.BufferedImage" %>
<%@ page import="test01.BufferedImageUtil" %>
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous">
<title>Output of "Simple QR sample with JSP"</title>
</head>
<body>
<%
String i_url = request.getParameter("i_url");
QRCodeWriter qrWriter = new QRCodeWriter();
BitMatrix bitMatrix = qrWriter.encode(i_url, BarcodeFormat.QR_CODE, 300, 300);
BufferedImage bImage = MatrixToImageWriter.toBufferedImage(bitMatrix);
%>
<div class="container">
<h2>Output of "Simple QR sample with JSP"</h2>
<p>Target URL: <%= i_url %></p>
<img src="<%= BufferedImageUtil.convert2DataURI(bImage, "png") %>"/>
<form action="/test01/">
<button type="submit" class="btn btn-primary">Back</button>
</form>
</div>
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js" integrity="sha384-B4gt1jrGC7Jh4AgTPSdUtOBvfO8shuf57BaghqFfPlYxofvL8/KUEfYiJOMMV+rV" crossorigin="anonymous"></script>
</body>
</html>
BufferedImageUtil クラス
今回、ポイントとなるのは BufferedImageUtil
クラスです。
ZXing の Java サンプルを探してみたのですが、いったんファイルに出力する例が多くヒットしました。しかし Web サービスの場合、できればテンポラリファイル作成は避けたいところです。
というわけで convert2DataURI
という、BufferedImage オブジェクトから Data URI をダイレクトに生成する簡単な関数を用意してみました。
package test01;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.xml.bind.DatatypeConverter;
public class BufferedImageUtil {
public static String convert2DataURI(BufferedImage bi, String type) throws IOException {
if (bi == null || type == null) {
return ""; // TODO: Default error image
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(bi, type, baos);
return "data:image/" + type + ";base64," + DatatypeConverter.printBase64Binary(baos.toByteArray());
}
}
エラー処理をサボっています。実際に使う際には、エラー画像の Data URI をあらかじめ用意しておいて、問題発生時にはそれを返してあげるのも良いとおもいます。
ライセンス
この投稿に含まれる私の作成した全てのコードは Creative Commons Zero ライセンスとします。自由にお使いください。
Enjoy!
以上、JSP で作成した Web サイトに、QRCode 表示の実装を試してみました。これをベースに、いろいろ機能を追加して遊んでみてください。
ではまた!