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

Java 圖片驗證碼完整實現指南:從 Servlet 到工具類的完整代碼解析

     編輯:Java 綜合教學

Java 圖片驗證碼完整實現指南

在 Web 應用開發中,圖片驗證碼是防止機器人惡意註冊、暴力破解登入的常用手段。本文將詳細介紹一個基於 Java Servlet 的完整驗證碼生成方案,包含核心 Servlet、工具類實現以及 web.xml 配置說明。

核心 Servlet:AuthImage

AuthImage 繼承自 HttpServlet,負責處理驗證碼圖片的生成與輸出。其核心邏輯在 service 方法中:

  • 設置響應頭防止快取,確保每次請求獲取最新驗證碼
  • 設定內容類型為 image/jpeg
  • 調用 VerifyCodeUtils 生成 4 位隨機驗證碼字串
  • 將驗證碼(轉小寫)存入 Session,供後續驗證使用
  • 生成 200x80 像素的驗證碼圖片並輸出到響應流
package hh.com.util;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class AuthImage extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {
    static final long serialVersionUID = 1L;

    public void service(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 禁用快取
        response.setHeader("Pragma", "No-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);
        response.setContentType("image/jpeg");

        // 生成隨機驗證碼
        String verifyCode = VerifyCodeUtils.generateVerifyCode(4);

        // 存入 Session
        HttpSession session = request.getSession(true);
        session.setAttribute("rand", verifyCode.toLowerCase());

        // 生成圖片
        int w = 200, h = 80;
        VerifyCodeUtils.outputImage(w, h, response.getOutputStream(), verifyCode);
    }
}

核心工具類:VerifyCodeUtils 詳細解析

VerifyCodeUtils 封裝了驗證碼生成的所有核心邏輯,包括字符源定義、隨機字串生成、圖片繪製、干擾線、噪點、扭曲變形等反 OCR 技術。

字符源與隨機生成

預設字符源排除易混淆字符(1,0,i,o),僅包含大寫字母與數字:

public static final String VERIFY_CODES = "23456789ABCDEFGHJKLMNPQRSTUVWXYZ";
private static Random random = new Random();

提供兩個重載方法生成指定長度驗證碼,支援自定義字符源。

圖片生成核心流程 outputImage

  1. 建立畫布:創建 BufferedImage,啟用抗鋸齒渲染提示
  2. 漸變背景:隨機選取 5 種顏色構建線性漸變背景
  3. 繪製干擾線:隨機生成 20 條干擾線,顏色在 160-200 範圍
  4. 添加噪點:按 5% 噪聲率隨機設置像素 RGB 值
  5. 扭曲變形:通過 shearX 和 shearY 方法對圖片進行正弦波形扭曲,大幅提升識別難度
  6. 繪製字符:使用 Algerian 斜體字體,每個字符隨機旋轉 ±45°,位置微調
  7. 輸出圖片:以 JPEG 格式寫入輸出流
public static void outputImage(int w, int h, OutputStream os, String code) throws IOException {
    int verifySize = code.length();
    BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
    Random rand = new Random();
    Graphics2D g2 = image.createGraphics();
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

    // 漸變背景
    Color[] colors = new Color[5];
    Color[] colorSpaces = { Color.WHITE, Color.CYAN, Color.GRAY, Color.LIGHT_GRAY, Color.MAGENTA, Color.ORANGE, Color.PINK, Color.YELLOW };
    float[] fractions = new float[colors.length];
    for (int i = 0; i < colors.length; i++) {
        colors[i] = colorSpaces[rand.nextInt(colorSpaces.length)];
        fractions[i] = rand.nextFloat();
    }
    Arrays.sort(fractions);
    // ... 繪製邊框、背景、干擾線、噪點、扭曲、字符 ...
    g2.dispose();
    ImageIO.write(image, "jpg", os);
}

輔助方法

  • getRandColor(fc, bc):生成指定範圍內的隨機顏色
  • getRandomIntColor() / getRandomRgb():生成隨機 RGB 整數值
  • shear/shearX/shearY:實現圖片的水平與垂直正弦波扭曲

web.xml 配置

將 AuthImage 映射至 /authImage 路徑,前端可通過 <img src="/authImage" /> 獲取驗證碼圖片。

<servlet>
    <servlet-name>AuthImage</servlet-name>
    <servlet-class>hh.com.util.AuthImage</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>AuthImage</servlet-name>
    <url-pattern>/authImage</url-pattern>
</servlet-mapping>

使用注意事項

  1. 需確保伺服器安裝 Algerian 字體,否則字符渲染會異常
  2. Session 存儲驗證碼時統一轉小寫,驗證時也應轉小寫比對
  3. 可根據安全需求調整干擾線數量、噪點率、扭曲幅度等參數
  4. 生產環境建議加入驗證碼失效時間控制(如 5 分鐘)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved