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

Java 生成圖片驗證碼完整實現(Servlet + 圖形繪製)

     編輯:Java 相關知識

前言

圖片驗證碼是 Web 應用防止機器註冊、暴力破解的基礎防線。本文提供一個基於 Servlet 的完整驗證碼生成實現,包含干擾線、隨機顏色、字符隨機、Session 存儲等核心功能,代碼可直接集成到項目中。

核心實現代碼

@Controller
public class ImgVerifyCode extends HttpServlet {
    private static final long serialVersionUID = 1L;
    // 配置參數
    private int width = 70;
    private int height = 30;
    private int codeCount = 5;
    private int xx = 0;
    private int fontHeight;
    private int codeY;
    // 字符池(去除易混淆字符 0/O, 1/I/l 等)
    private String[] codeSequence = {
        "1","2","3","4","5","6","7","8","9",
        "A","a","B","b","c","C","D","d","E","e","F","f","G","g",
        "z","X","Q","v"
    };

    @Override
    public void init() throws ServletException {
        // 可從 web.xml 讀取初始化參數
        xx = width / (codeCount + 2);
        fontHeight = height - 12;
        codeY = height - 8;
    }

    protected String images(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        // 1. 創建圖片緩衝區
        BufferedImage buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics2D gd = buffImg.createGraphics();
        Random random = new Random();

        // 2. 填充白色背景
        gd.setColor(Color.WHITE);
        gd.fillRect(0, 0, width, height);

        // 3. 設置字體
        Font font = new Font("Fixedsys", Font.PLAIN, fontHeight);
        gd.setFont(font);

        // 4. 繪製邊框
        gd.setColor(Color.BLACK);
        gd.drawRect(0, 0, width - 1, height - 1);

        // 5. 繪製 4 條干擾線
        gd.setColor(Color.BLACK);
        for (int i = 0; i < 4; i++) {
            int x = random.nextInt(width);
            int y = random.nextInt(height);
            int xl = random.nextInt(12);
            int yl = random.nextInt(12);
            gd.drawLine(x, y, x + xl, y + yl);
        }

        // 6. 生成隨機驗證碼並繪製
        StringBuffer randomCode = new StringBuffer();
        for (int i = 0; i < codeCount; i++) {
            String strRand = codeSequence[random.nextInt(codeSequence.length)];
            // 隨機顏色
            int red = random.nextInt(125);
            int green = random.nextInt(255);
            int blue = random.nextInt(200);
            gd.setColor(new Color(red, green, blue));
            gd.drawString(strRand, (i + 1) * xx, codeY);
            randomCode.append(strRand);
        }

        // 7. 存入 Session
        HttpSession session = req.getSession();
        session.setAttribute("validateCode", randomCode.toString());

        // 8. 禁止緩存
        resp.setHeader("Pragma", "no-cache");
        resp.setHeader("Cache-Control", "no-cache");
        resp.setDateHeader("Expires", 0);
        resp.setContentType("image/jpeg");

        // 9. 輸出圖片流
        ServletOutputStream sos = resp.getOutputStream();
        ImageIO.write(buffImg, "jpeg", sos);
        sos.close();
        return null;
    }
}

關鍵技術點解析

  1. 字符池設計:排除 0/O、1/I/l 等易混淆字符,提高用戶識別率。
  2. 干擾線:隨機位置、長度、顏色,增加 OCR 識別難度。
  3. 隨機顏色:每個字符顏色不同,進一步干擾機器識別。
  4. Session 存儲:驗證碼值存入 Session,登錄時比對後立即移除,防止重用。
  5. 禁止緩存:設置 HTTP 頭確保每次請求獲取新圖片。

前端調用示例

<img src="<%=request.getContextPath()%>/verifyCode.jpg" id="verifyImg" onclick="this.src=this.src+'?'+Math.random()" />
<input type="text" name="verifyCode" placeholder="請輸入驗證碼" />

後端驗證邏輯

String sessionCode = (String) session.getAttribute("validateCode");
String userCode = request.getParameter("verifyCode");
if (sessionCode != null && sessionCode.equalsIgnoreCase(userCode)) {
    // 驗證通過
    session.removeAttribute("validateCode"); // 用後即銷
} else {
    // 驗證失敗
}

進階擴展建議

  • 增加中文汉字支持,提高安全性。
  • 引入扭曲、噪點、背景圖片等高級干擾。
  • 集成 Google reCAPTCHA 或滑塊驗證替代傳統圖片驗證碼。
  • 使用 Redis 存儲驗證碼,支持分布式部署。

總結

本文提供的驗證碼生成 Servlet 代碼結構清晰、功能完整,涵蓋了圖形繪製、隨機生成、Session 管理、緩存控制等關鍵環節,可作為項目基礎安全組件直接使用或二次開發。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved