最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

如何在Java?Web項目中優(yōu)雅地實現(xiàn)驗證碼攔截與校驗

 更新時間:2025年09月16日 08:48:44   作者:微笑聽雨。  
驗證碼代碼用于防止機(jī)器人提交表單或訪問受限頁面,它是一個圖像或文本序列,需要輸入才能驗證身份,這篇文章主要介紹了如何在Java?Web項目中優(yōu)雅地實現(xiàn)驗證碼攔截與校驗的相關(guān)資料,需要的朋友可以參考下

前言

在 Web 開發(fā)中,很多網(wǎng)站都會對敏感頁面或公告信息做 驗證碼攔截,以防止爬蟲或惡意訪問。

比如訪問某些公告詳情頁時,必須先輸入驗證碼才能繼續(xù)瀏覽。

本文將以一個實際的案例為例,演示如何在 Java Web 項目中優(yōu)雅地實現(xiàn) Filter 攔截 + 驗證碼校驗 + 友好頁面展示

1. 需求分析

假設(shè)我們的系統(tǒng)中有以下目錄需要保護(hù):

xzbgg、zhzzsgg、zhzzbhxr、zhzbjggs、zhzzzgg、
xfzbgg、zhfcghxr、zhfcgjg、zhfzzgg、zhzbxx

攔截邏輯:

  • /xxx/index.jhtml 這樣的首頁不需要攔截;
  • /xxx/12345.jhtml 這樣的詳情頁必須輸入驗證碼才能訪問;
  • 驗證碼通過后,自動跳轉(zhuǎn)回用戶最初請求的頁面。

2. Filter 攔截實現(xiàn)

首先我們定義一個 CaptchaFilter,利用 正則表達(dá)式 精準(zhǔn)攔截需要驗證的頁面:

public class CaptchaFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {

        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;
        String uri = req.getRequestURI();

        // 定義需要保護(hù)的路徑前綴
        String[] protectedPaths = {
                "xzbgg", "zhzzsgg", "zhzzbhxr", "zhzbjggs", "zhzzzgg",
                "xfzbgg", "zhfcghxr", "zhfcgjg", "zhfzzgg", "zhzbxx"
        };

        // 匹配 /xxx/數(shù)字.jhtml 的請求
        String pattern = MessageFormat.format(".*/(?:{0})/\\d+\\.jhtml$", String.join("|", protectedPaths));

        if (uri.matches(pattern)) {
            HttpSession session = req.getSession();
            Boolean captchaPassed = (Boolean) session.getAttribute("captchaPassed");

            // 如果驗證碼已通過,放行并清理標(biāo)記
            if (Boolean.TRUE.equals(captchaPassed)) {
                chain.doFilter(request, response);
                session.removeAttribute("captchaPassed");
                return;
            }

            // 保存目標(biāo) URL,便于校驗成功后跳轉(zhuǎn)回來
            session.setAttribute("targetUrl", uri);

            // 轉(zhuǎn)發(fā)到驗證碼頁面
            req.getRequestDispatcher("/captcha.html").forward(req, resp);
            return;
        }

        // 其他請求直接放行
        chain.doFilter(request, response);
    }
}

這樣,所有訪問 /xxx/數(shù)字.jhtml 的請求都會被攔截,并跳轉(zhuǎn)到驗證碼頁面。

3. web.xml 配置

接著在 web.xml 中注冊 Filter 和兩個 Servlet

  • 一個生成驗證碼圖片(如 JCaptchaServlet);
  • 一個校驗驗證碼輸入(我們自定義的 CaptchaCheckServlet)。
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
         http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">

    <!-- 驗證碼攔截器 -->
    <filter>
        <filter-name>CaptchaFilter</filter-name>
        <filter-class>com.example.filter.CaptchaFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>CaptchaFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!-- 驗證碼圖片生成 Servlet (例如 JCaptcha) -->
    <servlet>
        <servlet-name>CaptchaServlet</servlet-name>
        <servlet-class>com.octo.captcha.module.servlet.image.SimpleImageCaptchaServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>CaptchaServlet</servlet-name>
        <url-pattern>/captcha.svl</url-pattern>
    </servlet-mapping>

    <!-- 驗證碼校驗 Servlet -->
    <servlet>
        <servlet-name>CaptchaCheckServlet</servlet-name>
        <servlet-class>com.example.servlet.CaptchaCheckServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>CaptchaCheckServlet</servlet-name>
        <url-pattern>/captcha/check</url-pattern>
    </servlet-mapping>
</web-app>

4. CaptchaCheckServlet 校驗邏輯

CaptchaCheckServlet 用來接收用戶輸入的驗證碼,并進(jìn)行校驗。

如果校驗失敗,重定向回 captcha.html?error=1。

public class CaptchaCheckServlet extends HttpServlet {

    private ImageCaptchaService captchaService;

    @Override
    public void init() throws ServletException {
        super.init();
        WebApplicationContext appCtx =
                WebApplicationContextUtils.getWebApplicationContext(getServletContext());
        captchaService = BeanFactoryUtils.beanOfTypeIncludingAncestors(
                appCtx, ImageCaptchaService.class);

        if (captchaService == null) {
            throw new ServletException("CaptchaService 未初始化,請檢查 Spring 配置");
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {

        HttpSession session = req.getSession();
        String captchaId = session.getId();
        String inputCode = req.getParameter("code");

        boolean passed;
        try {
            passed = captchaService.validateResponseForID(captchaId, inputCode);
        } catch (Exception e) {
            passed = false;
        }

        if (passed) {
            // 驗證成功,設(shè)置標(biāo)記并跳轉(zhuǎn)回原頁面
            session.setAttribute("captchaPassed", true);
            String targetUrl = (String) session.getAttribute("targetUrl");
            session.removeAttribute("targetUrl");

            if (targetUrl != null) {
                resp.sendRedirect(targetUrl);
            } else {
                resp.sendRedirect(req.getContextPath() + "/");
            }
        } else {
            // 驗證失敗,重定向并附帶錯誤標(biāo)記
            resp.sendRedirect(req.getContextPath() + "/captcha.html?error=1");
        }
    }
}

5. 驗證碼頁面(HTML)

驗證碼頁面保留為 純 HTML,通過 JavaScript 獲取 URL 參數(shù) error 來顯示錯誤提示。

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>請輸入驗證碼</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <style>
        body {
            font-family: "Microsoft YaHei", Arial, sans-serif;
            display: flex;
            justify-content: center;
            align-items: center;
            min-height: 100vh;
            margin: 0;
            background: #f4f6f9;
        }
        .captcha-container {
            background: #fff;
            padding: 2rem;
            border-radius: 12px;
            box-shadow: 0 4px 12px rgba(0,0,0,0.1);
            text-align: center;
            width: 300px;
        }
        h2 {
            margin-bottom: 1.2rem;
            font-size: 1.2rem;
            color: #333;
        }
        .error {
            color: red;
            margin-bottom: 1rem;
            display: none;
        }
        img {
            cursor: pointer;
            margin-bottom: 1rem;
            border: 1px solid #ddd;
            border-radius: 6px;
        }
        input[type="text"] {
            width: 100%;
            padding: 10px;
            border: 1px solid #ccc;
            border-radius: 6px;
            font-size: 1rem;
            margin-bottom: 1rem;
        }
        button {
            width: 100%;
            padding: 10px;
            border: none;
            border-radius: 6px;
            background: #007bff;
            color: white;
            font-size: 1rem;
            cursor: pointer;
        }
        button:hover {
            background: #0056b3;
        }
        .tip {
            margin-top: 0.8rem;
            font-size: 0.9rem;
            color: #666;
        }
    </style>
</head>
<body>
<div class="captcha-container">
    <h2>請輸入驗證碼</h2>

    <div class="error" id="errorMsg">驗證碼錯誤,請重新輸入</div>

    <form action="/zhcms/captcha/check" method="post">
        <img src="/zhcms/captcha.svl"
             onclick="this.src='/zhcms/captcha.svl?'+Math.random()"
             alt="驗證碼" title="點擊圖片更換驗證碼"/>
        <input type="text" name="code" placeholder="請輸入驗證碼" required/>
        <button type="submit">提交</button>
        <div class="tip">看不清?點擊圖片刷新驗證碼</div>
    </form>
</div>

<script>
    // 從 URL 獲取參數(shù)
    const params = new URLSearchParams(window.location.search);
    if (params.get("error") === "1") {
        document.getElementById("errorMsg").style.display = "block";
    }
</script>
</body>
</html>

頁面效果如圖所示:

6. 常見問題 Q&A

Q1: 為什么驗證碼頁面用 JSP 會被攔截?

A: 因為 Filter 攔截了 .jhtml 之外的請求時,轉(zhuǎn)發(fā)到 JSP 也會觸發(fā)過濾邏輯,容易形成死循環(huán)。改成 .html 并使用 JavaScript 處理錯誤提示即可。

Q2: 驗證碼圖片不顯示?

A: 檢查 captcha.svl 是否正確映射到 SimpleImageCaptchaServlet。同時確認(rèn)瀏覽器是否緩存了圖片,可以通過 ?Math.random() 動態(tài)刷新。

Q3: 校驗通過后沒有跳轉(zhuǎn)回原頁面?

A: 確保在 Filter 里使用 session.setAttribute("targetUrl", uri) 保存目標(biāo)地址,并在 CaptchaCheckServlet 里取出并重定向。

Q4: 如何擴(kuò)展更多攔截目錄?

A: 只需在 protectedPaths 數(shù)組里新增路徑名即可,例如 "newpath1", "newpath2"。

7. 總結(jié)

通過以上幾個步驟,我們就實現(xiàn)了一個完整的驗證碼攔截機(jī)制:

  1. Filter 攔截:利用正則表達(dá)式精確攔截 /xxx/數(shù)字.jhtml 的請求;
  2. 驗證碼校驗:用戶輸入后由 CaptchaCheckServlet 校驗,成功后跳轉(zhuǎn)回原始頁面;
  3. 用戶體驗優(yōu)化:驗證碼頁面保持 HTML,支持錯誤提示,UI 簡潔美觀;
  4. 常見問題處理:避免死循環(huán),解決驗證碼圖片緩存問題。

這種實現(xiàn)方式簡單清晰、可維護(hù)性強,非常適合需要在項目中批量攔截頁面并加上驗證碼驗證的場景。

到此這篇關(guān)于如何在Java Web項目中優(yōu)雅地實現(xiàn)驗證碼攔截與校驗的文章就介紹到這了,更多相關(guān)Java Web驗證碼攔截與校驗內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java獲取隨機(jī)數(shù)的3種方法

    Java獲取隨機(jī)數(shù)的3種方法

    本篇文章主要介紹了Java獲取隨機(jī)數(shù)的3種方法,現(xiàn)在分享給大家,也給大家做個參考,感興趣的小伙伴們可以參考一下。
    2016-11-11
  • Java使用hutool實現(xiàn)文件大小的友好輸出

    Java使用hutool實現(xiàn)文件大小的友好輸出

    這篇文章主要為大家詳細(xì)介紹了Java如何使用hutool實現(xiàn)文件大小的友好輸出,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價值,感興趣的小伙伴可以了解下
    2023-11-11
  • jdbc連接sqlserver數(shù)據(jù)庫示例

    jdbc連接sqlserver數(shù)據(jù)庫示例

    這篇文章主要介紹了jdbc連接sqlserver數(shù)據(jù)庫示例,需要的朋友可以參考下
    2014-04-04
  • Java項目開發(fā)命名規(guī)范(動力節(jié)點Java學(xué)院整理)

    Java項目開發(fā)命名規(guī)范(動力節(jié)點Java學(xué)院整理)

    定義這個規(guī)范的目的是讓項目中所有的文檔都看起來像一個人寫的,增加可讀性,減少項目組中因為換人而帶來的損失。下面給大家分享java開發(fā)命名規(guī)范,一起看看吧
    2017-03-03
  • 實現(xiàn)了基于TCP的Java Socket編程實例代碼

    實現(xiàn)了基于TCP的Java Socket編程實例代碼

    這篇文章主要介紹了基于TCP的Java Socket編程實例代碼,有需要的朋友可以參考一下
    2013-12-12
  • java多線程抓取鈴聲多多官網(wǎng)的鈴聲數(shù)據(jù)

    java多線程抓取鈴聲多多官網(wǎng)的鈴聲數(shù)據(jù)

    很容易就能發(fā)現(xiàn)通過改變 listId和page就能從服務(wù)器獲取鈴聲的json數(shù)據(jù), 通過解析json數(shù)據(jù), 可以看到都帶有{"hasmore":1,"curpage":1}這樣子的指示,通過判斷hasmore的值,決定是否進(jìn)行下一頁的抓取。 但是通過上面這個鏈接返回的json中不帶有鈴聲的下載地址
    2016-04-04
  • Javaweb中使用Jdom解析xml的方法

    Javaweb中使用Jdom解析xml的方法

    Jdom是一個開源項目,基于樹形結(jié)構(gòu),利用純java的技術(shù)對XML文檔實現(xiàn)解析,生成,序列化以及多種操作.這篇文章主要介紹了Javaweb中使用Jdom解析xml的方法的相關(guān)資料,需要的朋友可以參考下
    2016-09-09
  • java反射深入剖析(推薦)

    java反射深入剖析(推薦)

    下面小編就為大家?guī)硪黄猨ava反射深入剖析。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-07-07
  • java8 LocalDate 使用詳解

    java8 LocalDate 使用詳解

    這篇文章主要介紹了java8 LocalDate 使用詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-08-08
  • springboot創(chuàng)建監(jiān)聽和處理事件的操作方法

    springboot創(chuàng)建監(jiān)聽和處理事件的操作方法

    這篇文章主要介紹了springboot創(chuàng)建監(jiān)聽和處理事件的操作方法,使用Spring Boot的事件機(jī)制來監(jiān)聽和處理事件有多種優(yōu)勢,本文給大家介紹的非常詳細(xì),需要的朋友參考下吧
    2024-07-07

最新評論

会东县| 富阳市| 泰宁县| 肇州县| 双流县| 宣城市| 称多县| 吉水县| 天长市| 鄯善县| 奉新县| 曲水县| 高淳县| 南乐县| 五峰| 乌拉特后旗| 和顺县| 大城县| 丁青县| 红安县| 安达市| 阿巴嘎旗| 太康县| 大名县| 永登县| 海城市| 焦作市| 安陆市| 庄河市| 都兰县| 洛浦县| 新竹市| 凤山市| 南昌市| 张家界市| 手游| 太仆寺旗| 隆尧县| 武陟县| 温宿县| 安溪县|