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

Struts2 實現圖形驗證碼生成與驗證完整實戰代碼

     編輯:Java 相關知識

整體流程

  1. 專用 Action 生成驗證碼圖片 → 寫入 Session
  2. JSP 頁面以 <img> 標籤請求圖片,點擊刷新
  3. 表單提交時攜帶用戶輸入 → Action 驗證與 Session 比對

核心代碼實現

1. 驗證碼生成 Action

package com.zhuguang.action;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.interceptor.*;
import com.opensymphony.xwork2.ActionSupport;
import com.sun.image.codec.jpeg.*;

public class CaptchaAction extends ActionSupport 
        implements SessionAware, ServletResponseAware {

    private Map session;
    private HttpServletResponse response;

    @Override
    public String execute() throws Exception {
        // 禁用緩存
        response.setHeader("Cache-Control", "no-cache");
        response.setHeader("Pragma", "no-cache");
        response.setDateHeader("Expires", 0);

        int width = 50, height = 20;
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics g = image.getGraphics();

        // 背景噪點
        g.setColor(getRandomColor());
        g.fillRect(0, 0, width, height);

        // 繪製驗證碼
        g.setFont(new Font("Arial", Font.BOLD, 18));
        g.setColor(getRandomColor());
        String code = String.valueOf(System.currentTimeMillis() % 9000 + 1000); // 4 位數
        session.put("captchaCode", code);
        g.drawString(code, (int)(width * 0.1), (int)(height * 0.8));
        g.dispose();

        // 輸出 JPEG
        JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(response.getOutputStream());
        encoder.encode(image);
        response.getOutputStream().flush();
        return null; // 直接輸出圖片流,不跳轉
    }

    private Color getRandomColor() {
        return new Color(
            (int)(Math.random() * 256),
            (int)(Math.random() * 256),
            (int)(Math.random() * 256)
        );
    }

    // SessionAware, ServletResponseAware 注入方法省略...
}

2. struts.xml 配置

<action name="captcha" class="com.zhuguang.action.CaptchaAction">
    <!-- 無 result,直接輸出圖片流 -->
</action>

<action name="login" class="com.zhuguang.action.LoginAction" method="execute">
    <result name="success">/success.jsp</result>
    <result name="error">/login.jsp</result>
</action>

3. JSP 頁面整合

<%@ taglib prefix="s" uri="/struts-tags" %>
<script>
function refreshCaptcha(img) {
    img.src = '${pageContext.request.contextPath}/captcha.action?t=' + new Date().getTime();
}
</script>

<form action="login" method="post">
    用戶名:<input name="username" /><br/>
    密碼:<input type="password" name="password" /><br/>
    驗證碼:<input name="captcha" maxlength="4" />
    <img id="captchaImg" src="${pageContext.request.contextPath}/captcha.action" 
         onclick="refreshCaptcha(this)" title="點擊刷新" /><br/>
    <input type="submit" value="登錄" />
</form>

4. 登錄驗證 Action

public class LoginAction extends ActionSupport implements SessionAware {
    private Map session;
    private String captcha; // 用戶輸入

    public String execute() {
        String realCode = (String) session.get("captchaCode");
        if (realCode != null && realCode.equalsIgnoreCase(captcha)) {
            session.remove("captchaCode"); // 一次性失效
            return SUCCESS;
        }
        addFieldError("captcha", "驗證碼錯誤");
        return ERROR;
    }
    // getter/setter + SessionAware 注入省略
}

關鍵細節總結

  • 時間戳參數:?t=timestamp 防止瀏覽器緩存圖片導致不刷新。
  • 忽略大小寫比對:equalsIgnoreCase 提升用戶體驗。
  • 用後即銷:驗證成功後移除 Session 碼,防止重放攻擊。
  • 無 Result 返回:圖片流直接寫 response.getOutputStream(),Action 返回 null。

生產環境建議:引入 Kaptcha 或 Hutool Captcha 等成熟庫,支援干擾線、字體扭曲、中文驗證碼等進階功能,安全性與可維護性更強。

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