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

Spring MVC 實作圖形驗證碼:完整 Controller 範例

     編輯:Java 相關知識

Spring MVC 伺服器端圖形驗證碼生成與驗證完整實作

本文提供一個生產級的 Spring MVC @RestController,生成帶干擾線、隨機顏色、可配置長度的 JPEG 驗證碼圖片,並將驗證碼存入 HttpSession 供後續表單驗證使用。

完整 Controller 程式碼

@RestController
@RequestMapping("")
public class ImgCodeController {

    @Autowired
    private RedisTemplate cache; // 可選:分散式 Session 支援

    private int width = 90;
    private int height = 30;
    private int codeCount = 4;
    private int xx = 15;
    private int fontHeight = 18;
    private int codeY = 16;

    private char[] codeSequence = {
        'A','B','C','D','E','F','G','H','I','J','K','L','M',
        'N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
        '0','1','2','3','4','5','6','7','8','9'
    };

    @RequestMapping("/checkCode")
    protected void doGetCode(HttpServletRequest request, HttpServletResponse response) throws IOException {
        // 1. 禁用快取
        response.setHeader("Pragma", "No-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);
        response.setContentType("image/jpeg");

        // 2. 建立圖片緩衝區
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics g = image.getGraphics();
        Random random = new Random();

        // 3. 填充背景
        g.setColor(getRandColor(200, 250));
        g.fillRect(0, 0, width, height);

        // 4. 設定字體
        g.setFont(new Font("Times New Roman", Font.PLAIN, fontHeight));

        // 5. 畫邊框
        g.setColor(new Color(20, 20, 20));
        g.drawRect(0, 0, width - 1, height - 1);

        // 6. 畫干擾線
        g.setColor(getRandColor(160, 200));
        for (int i = 0; i < 155; i++) {
            int x = random.nextInt(width);
            int y = random.nextInt(height);
            int xl = random.nextInt(12);
            int yl = random.nextInt(12);
            g.drawLine(x, y, x + xl, y + yl);
        }

        // 7. 生成並繪製驗證碼字元
        StringBuffer randomCode = new StringBuffer();
        for (int i = 0; i < codeCount; i++) {
            String code = String.valueOf(codeSequence[random.nextInt(codeSequence.length)]);
            int red = 20 + random.nextInt(110);
            int green = 20 + random.nextInt(110);
            int blue = 20 + random.nextInt(110);
            g.setColor(new Color(red, green, blue));
            g.drawString(code, (i + 1) * xx, codeY);
            randomCode.append(code);
        }

        // 8. 存入 Session
        HttpSession session = request.getSession();
        session.setAttribute("code", randomCode.toString());

        // 9. 輸出圖片
        g.dispose();
        ServletOutputStream sos = response.getOutputStream();
        ImageIO.write(image, "jpeg", sos);
        sos.close();
    }

    private Color getRandColor(int fc, int bc) {
        Random random = new Random();
        if (fc > 255) fc = 255;
        if (bc > 255) bc = 255;
        int r = fc + random.nextInt(bc - fc);
        int g = fc + random.nextInt(bc - fc);
        int b = fc + random.nextInt(bc - fc);
        return new Color(r, g, b);
    }

    // Getter/Setter 省略...
}

核心流程說明

  1. 快取控制:設定 Header 禁止瀏覽器/Proxy 快取驗證碼圖片,確保每次請求都是新圖。
  2. 圖片建立:BufferedImage.TYPE_INT_RGB 建立記憶體圖片,Graphics 進行繪圖操作。
  3. 干擾線:155 條隨機短線,顏色範圍 160~200,干擾 OCR 識別。
  4. 字元繪製:從 36 個字元(A-Z, 0-9)隨機挑選 4 個,每個字元隨機顏色(RGB 各 20~130),drawString 繪製於計算位置。
  5. Session 儲存:驗證碼字串存入 HttpSession,鍵為 "code"。
  6. 輸出:ImageIO.write(image, "jpeg", outputStream) 直接寫入 HTTP 回應串流。

前端整合範例

<img src="/checkCode" id="captchaImg" onclick="this.src='/checkCode?t='+Date.now()" />
<input type="text" name="captcha" />

點擊圖片刷新(加時間戳避免瀏覽器快取)。表單提交時後端比對 session.getAttribute("code") 與用戶輸入(忽略大小寫)。

生產環境強化建議

  • 使用 Google Kaptcha 或 SimpleCaptcha 成熟庫,支援更多字型、噪點、扭曲效果。
  • 分散式部署時,Session 需共享(Redis、Sticky Session),或改用 JWT/Redis 直接存儲驗證碼(Key: UUID, Value: code, TTL: 5 分鐘)。
  • 加入請求頻率限制(如 Bucket4j),防止暴力刷新驗證碼接口。
  • 考慮無障礙:提供語音驗證碼選項。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved