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

SSH框架電商專案實戰(十八):以 Filter 實作購物流程登入攔截與導向

     編輯:Java 相關知識

前言

在上一階段我們完成購物車的基本操作,但仍缺少一個關鍵環節:當使用者點擊「結帳」時,系統必須先判斷使用者是否已登入。若未登入,需攔截請求並導向登入頁;登入成功後,再自動跳回原本想前往的頁面(如訂單確認頁)。這正是 Servlet Filter(過濾器)的經典應用場景。

核心邏輯:登入攔截與導向機制

整個流程可拆解為三步:

  1. 攔截:在 web.xml 設定需攔截的 URL 模式(如 /user/confirm.jsp),當使用者請求符合模式時,容器會先執行自訂 Filter。
  2. 判斷與保存:Filter 內檢查 Session 是否存在 user 屬性。若無,表示未登入,則將「原始請求路徑 + 參數」組合並存入 Session(鍵名 goURL),再重導向至登入頁(ulogin.jsp)。
  3. 放行或處理:若 Session 已有使用者資訊,直接呼叫 chain.doFilter() 放行;登入成功後,Action 會讀取 Session 中的 goURL 決定跳轉目標。

程式碼實作

1. 自訂 Filter:UserFilter

public class UserFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // 初始化邏輯(若有)
    }

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

        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse res = (HttpServletResponse) response;

        // 1. 檢查 Session 是否有登入用戶
        if (req.getSession().getAttribute("user") == null) {
            // 2. 保存原始請求 URL 含參數
            String goURL = req.getServletPath();
            String queryString = req.getQueryString();
            if (queryString != null) {
                goURL += "?" + queryString;
            }
            req.getSession().setAttribute("goURL", goURL);
            req.getSession().setAttribute("error", "請先登入!");

            // 3. 重導向至登入頁
            res.sendRedirect(req.getContextPath() + "/ulogin.jsp");
        } else {
            // 已登入,放行
            chain.doFilter(request, response);
        }
    }

    @Override
    public void destroy() {
        // 銷毀邏輯(若有)
    }
}

2. web.xml 設定攔截路徑

<filter>
    <filter-name>UserFilter</filter-name>
    <filter-class>com.shop.filter.UserFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>UserFilter</filter-name>
    <url-pattern>/user/confirm.jsp</url-pattern>
</filter-mapping>

3. 登入 Action:UserAction.login()

@Controller("userAction")
@Scope("prototype")
public class UserAction extends BaseAction<User> {

    public String login() {
        // 驗證帳密
        model = userService.login(model);
        if (model == null) {
            session.put("error", "登入失敗");
            return "login";
        }

        // 登入成功,存入 Session
        session.put("user", model);

        // 依 goURL 決定跳轉
        if (session.get("goURL") == null) {
            return "index";          // 無導向目標,回首頁
        } else {
            return "goURL";          // 有導向目標,交由 Struts 結果型別處理
        }
    }
}

4. Struts 結果型別設定(struts.xml)

<action name="user_*" class="userAction" method="{1}">
    <result name="login">/ulogin.jsp</result>
    <result name="index">/index.jsp</result>
    <result name="goURL" type="redirect">${session.goURL}</result>
</action>

關鍵在於 type="redirect" 搭配 ${session.goURL},利用 OGNL 表達式從 Session 取出原始 URL 並重導向。

5. Service 層驗證邏輯

@Service("userService")
public class UserServiceImpl extends BaseServiceImpl<User> implements UserService {

    @Override
    public User login(User user) {
        String hql = "FROM User u WHERE u.login = :login AND u.pass = :pass";
        return (User) getSession()
                .createQuery(hql)
                .setParameter("login", user.getLogin())
                .setParameter("pass", user.getPass())
                .uniqueResult();
    }
}

後續優化方向

目前攔截點在「訂單確認頁」,更理想的是在「加入購物車」前就檢查登入狀態。但因加入購物車是透過 Action 處理,若要攔截 Action 請求,應改用 Struts2 Interceptor(攔截器) 而非 Filter。後續篇幅將補充 Interceptor 實作。

小結

本文示範如何以 Servlet Filter 實作「登入攔截 → 保存目標 URL → 登入後自動導回」的完整流程,搭配 Struts2 結果型別靈活導向,達到無縫購物體驗。程式碼結構清晰,易於擴充與維護。

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