Struts 2 本質是一個**核心過濾器** (`StrutsPrepareAndExecuteFilter`),攔截請求、實例化 Action、注入參數、調用業務方法、根據結果視圖轉發。本文通過一個「用戶名校驗」最小案例,演示**web.xml、struts.xml、Action 類、JSP 頁面**四大組件完整串聯。
src/ ├── com.struts.action │ └── TestAction.java ├── struts.xml web/ ├── WEB-INF/ │ └── web.xml ├── index.jsp └── success.jsp
<web-app>
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
關鍵點:`url-pattern>/*` 攔截所有請求,Struts 內部會放行靜態資源 (需配置 `struts.action.excludePattern`)。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN" "https://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
<package name="default" namespace="/" extends="struts-default">
<action name="testAction" class="com.struts.action.TestAction">
<result name="success">/success.jsp</result>
<result name="error">/index.jsp</result>
</action>
</package>
</struts>
namespace="/" + name="testAction" → 匹配 URL `class 指定 Action 實現類 (每請求一實例,線程安全)result 名稱對應 Action 方法返回字串<%@ page contentType="text/html;charset=UTF-8" %>
<html>
<body>
<form method="post" action="testAction">
名稱:<input type="text" name="name"/>
<input type="submit" value="提交"/>
</form>
</body>
</html>
表單提交到 `testAction`,Struts 根據 `struts.xml` 找到對應 Action。
package com.struts.action;
public class TestAction {
// 1. 屬性驅動:自動接收表單參數 name (需提供 getter/setter)
private String name;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
// 2. 默認執行方法:execute(),返回結果字串
public String execute() {
if ("username".equals(name)) {
return "success"; // 對應 result name="success"
} else {
return "error"; // 對應 result name="error"
}
}
}
<%@ page contentType="text/html;charset=UTF-8" %>
<html>
<body>
<h3>歡迎,${name}!登錄成功。</h3> <!-- EL 表達式獲取 Action 屬性 -->
</body>
</html>
HTTP Request (POST /testAction)
│
▼
StrutsPrepareAndExecuteFilter.doFilter()
│
├── ActionMapping 查找 (struts.xml) → 找到 testAction
│
├── ActionProxy 創建
│
├── ActionInvocation 鏈構建 (Interceptor Stack)
│ ├── ParamsInterceptor → 設置 Action.name = "username" (OGNL 表達式)
│ ├── ConversionErrorInterceptor
│ └── ... (默認 defaultStack)
│
├── Action 實例化 (每請求一個新實例)
│
├── Action.execute() 調用 → 返回 "success"
│
├── Result 處理 (DispatcherResult)
│ → forward 到 /success.jsp
│
▼
HTTP Response (Rendered success.jsp)
| 功能 | 配置/代碼 | 說明 |
|---|---|---|
| 指定非 execute 方法 | ` | 或實現 `MethodAware` 接口,或使用 `!` 通配符映射 |
| 參數自動注入 | Action 提供 `setXxx()` / `getXxx()` | OGNL 表達式支持巢狀屬性:`user.name` → `setUser(new User())` + `user.setName()` |
| 校驗 | 實現 `Validateable` / 註解 `@Validation` / XML `-validation.xml` | 校驗失敗默認返回 `input` 結果 |
| 自定義攔截器 | 實現 `Interceptor` → `struts.xml` 定義 ` | 可用於登錄檢查、日誌、事務、權限 |
| 文件上傳 | ` | 默認大小限制 2MB,可配置 |
Struts 2 以**「過濾器 + XML 映射 + POJO Action + 結果視圖」**的輕量架構,實現了請求處理的標準化流程。掌握 **web.xml → struts.xml → Action (屬性驅動 + execute) → Result** 核心鏈路,理解 **攔截器鏈、OGNL 表達式、結果類型** 三大核心機制,即可快速構建基於 Struts 2 的 Web 應用。雖然現代項目多遷移至 Spring MVC,但 Struts 2 的**模型驅動、攔截器鏈、插件化架構**思想仍具參考價值。