How to Generate QR Codes in Java with ZXing: A Step‑by‑Step Guide

This tutorial explains why QR codes are everywhere, introduces their basic properties, and shows how to generate static and dynamic QR codes in Java using the ZXing library, Maven dependencies, Spring MVC, and optional Base64 streaming for front‑end display.

Programmer DD
Programmer DD
Programmer DD
How to Generate QR Codes in Java with ZXing: A Step‑by‑Step Guide

1. Introduction

QR codes have become ubiquitous in daily life, from street‑food stalls to pandemic control, and developers often need to generate them programmatically. This article explores how to create QR codes with Java.

2. About QR Codes

QR codes encode information as a two‑dimensional pattern. While the encoding/decoding algorithm is abstracted away for developers, it is useful to know a few properties:

Identical content produces identical QR codes when the same algorithm and settings are used.

More content results in a more complex pattern, which increases decoding time.

QR codes support error‑correction levels; higher levels allow more data to be stored but increase visual complexity.

These points guide practical adjustments during development.

3. Generating QR Codes in Java

We use Google’s open‑source ZXing library (1D/2D barcode processing) to create QR codes. First, add the Maven dependencies:

<dependency>
    <groupId>com.google.zxing</groupId>
    <artifactId>core</artifactId>
    <version>3.4.0</version>
</dependency>
<dependency>
    <groupId>com.google.zxing</groupId>
    <artifactId>javase</artifactId>
    <version>3.4.0</version>
</dependency>

Basic code to generate a simple QR image:

QRCodeWriter qrCodeWriter = new QRCodeWriter();
// content, format, width, height
BitMatrix bitMatrix = qrCodeWriter.encode("https://www.felord.cn", BarcodeFormat.QR_CODE, 30, 30);
MatrixToImageWriter.writeToPath(bitMatrix, "png", Paths.get("E:\\workbase\\qr.png"));

To control character set and error‑correction level:

QRCodeWriter qrCodeWriter = new QRCodeWriter();
Map<EncodeHintType, Object> hints = new HashMap<>();
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
BitMatrix bitMatrix = qrCodeWriter.encode("https://www.felord.cn", BarcodeFormat.QR_CODE, 80, 80, hints);
MatrixToImageWriter.writeToPath(bitMatrix, "png", Paths.get("E:\\workbase\\qr.png"));

ZXing can also write the image to a stream, allowing Base64 conversion for front‑end use:

ByteArrayOutputStream baos = new ByteArrayOutputStream();
MatrixToImageWriter.writeToStream(bitMatrix, "png", baos);
byte[] bytes = baos.toByteArray();
String base64Image = new BASE64Encoder().encode(bytes);

Display the Base64 image in HTML:

<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFAAAABQAQAAAACmas8..." alt="">
Base64 images are convenient for small QR codes, but large strings increase rendering cost; weigh the trade‑offs in production.

4. Dynamic QR Codes

For on‑the‑fly QR generation, expose a servlet endpoint using Spring MVC:

package cn.felord.qr.format;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.WriterException;
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 org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * @author dax
 * @since 2020/2/29 21:09
 */
@Controller
@RequestMapping("/qr")
public class QRController {

    @GetMapping("/felord")
    public void gen(HttpServletResponse response) throws IOException, WriterException {
        response.setContentType("image/png");
        ServletOutputStream out = response.getOutputStream();
        out.write(imageBytes());
        out.flush();
        out.close();
    }

    private byte[] imageBytes() throws IOException, WriterException {
        QRCodeWriter writer = new QRCodeWriter();
        Map<EncodeHintType, Object> hints = new HashMap<>();
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
        BitMatrix matrix = writer.encode("https://www.felord.cn", BarcodeFormat.QR_CODE, 80, 80, hints);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        MatrixToImageWriter.writeToStream(matrix, "png", baos);
        return baos.toByteArray();
    }
}

5. Practical Tips

Avoid embedding sensitive plain‑text data in QR codes; consider hashing or masking.

For long URLs, use a short‑link service to reduce payload.

Ensure QR codes are unique for a limited time by adding random noise.

Consider third‑party wrappers like qrext4j for additional features.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

BackendJavaQR codeSpring MVCZXing
Programmer DD
Written by

Programmer DD

A tinkering programmer and author of "Spring Cloud Microservices in Action"

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.