首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 圖形驗證碼生成完整實作 (可配置、抗干擾)

     編輯:Java 相關知識

核心功能特性

  • 支援自訂寬高、字元長度、字體、字號、干擾線密度、顏色範圍。
  • 單例模式 + Builder 鏈式配置,執行緒安全。
  • 自動存入 Session,防快取 headers,直接輸出 JPEG 流。
  • 每字元隨機顏色、位置微調,提升識別難度。

完整工具類

public final class CaptchaFactory {
    private static final char[] CHAR_POOL = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".toCharArray();
    private static final CaptchaFactory INSTANCE = new CaptchaFactory();

    // 可配置預設值
    private int width = 120, height = 40, length = 4, fontSize = 24, xOffset = 20, yOffset = 28;
    private String fontFamily = "Arial";

    private CaptchaFactory() {}

    public static CaptchaFactory getInstance() { return INSTANCE; }

    // 鏈式配置方法
    public CaptchaFactory size(int w, int h) { this.width = w; this.height = h; return this; }
    public CaptchaFactory length(int len) { this.length = len; return this; }
    public CaptchaFactory font(String family, int size) { this.fontFamily = family; this.fontSize = size; return this; }
    public CaptchaFactory offset(int x, int y) { this.xOffset = x; this.yOffset = y; return this; }

    /** 核心生成邏輯,返回 Map{code, image} */
    public Map generate() {
        BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics2D g = img.createGraphics();
        // 背景
        g.setColor(randomColor(200, 255));
        g.fillRect(0, 0, width, height);
        // 字體
        g.setFont(new Font(fontFamily, Font.BOLD, fontSize));
        // 干擾線
        g.setColor(randomColor(160, 200));
        for (int i = 0; i < 30; i++) {
            int x1 = random.nextInt(width), y1 = random.nextInt(height);
            int x2 = x1 + random.nextInt(12), y2 = y1 + random.nextInt(12);
            g.drawLine(x1, y1, x2, y2);
        }
        // 字元
        StringBuilder code = new StringBuilder();
        for (int i = 0; i < length; i++) {
            char ch = CHAR_POOL[random.nextInt(CHAR_POOL.length)];
            code.append(ch);
            g.setColor(new Color(random.nextInt(100), random.nextInt(100), random.nextInt(100)));
            g.drawString(String.valueOf(ch), i * xOffset + 10, yOffset);
        }
        g.dispose();
        return Map.of("code", code.toString(), "image", img);
    }

    /** 輸出至 HttpServletResponse */
    public void write(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        Map captcha = generate();
        String code = (String) captcha.get("code");
        BufferedImage img = (BufferedImage) captcha.get("image");

        HttpSession session = req.getSession();
        session.setAttribute("captcha_code", code); // 存入 Session 驗證用

        // 防快取
        resp.setHeader("Pragma", "No-cache");
        resp.setHeader("Cache-Control", "no-cache");
        resp.setDateHeader("Expires", 0);
        resp.setContentType("image/jpeg");

        ImageIO.write(img, "jpeg", resp.getOutputStream());
    }

    private final Random random = new Random();
    private Color randomColor(int min, int max) {
        int r = min + random.nextInt(max - min);
        int g = min + random.nextInt(max - min);
        int b = min + random.nextInt(max - min);
        return new Color(r, g, b);
    }
}

Servlet 整合範例

@WebServlet("/captcha")
public class CaptchaServlet extends HttpServlet {
    @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        CaptchaFactory.getInstance().size(130, 45).length(5).write(req, resp);
    }
}

前端使用

<img id="captchaImg" src="/captcha" onclick="this.src='/captcha?t='+Date.now()" style="cursor:pointer">
<input type="text" name="captcha" placeholder="輸入驗證碼">

後端驗證

String input = req.getParameter("captcha");
String sessionCode = (String) req.getSession().getAttribute("captcha_code");
if (sessionCode != null && sessionCode.equalsIgnoreCase(input)) {
    // 驗證通過
    req.getSession().removeAttribute("captcha_code"); // 一次性失效
}
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved