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

Struts 2 核心架構解析:從請求處理到攔截器鏈完整流程

     編輯:Java 綜合教學

Struts 2 定位

基於 WebWork 發展的 MVC 框架,核心特點:POJO Action、攔截器鏈、OGNL 表達式、結果類型多樣。Struts 1 已停止維護,現代專案建議 Spring MVC / Spring Boot。

核心組件架構

用戶請求
    ↓
[過濾器: StrutsPrepareAndExecuteFilter]
    ↓
[ActionMapping] → 根據 URL 找 Action 配置
    ↓
[ActionProxy] → 建立 ActionInvocation
    ↓
[攔截器鏈] → 按順序執行 18 個預設攔截器
    ├─ 1. ServletConfigInterceptor
    ├─ 2. ParametersInterceptor (參數注入)
    ├─ 3. ConversionErrorInterceptor
    ├─ 4. PrepareInterceptor (Preparable)
    ├─ 5. ModelDrivenInterceptor
    ├─ 6. ... (共 18 個,defaultStack)
    ↓
[Action 實例] → 執行 execute()/自定義方法
    ↓
[結果處理] → Result 類型 (dispatcher/redirect/stream/json...)
    ↓
響應返回

web.xml 核心配置

<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>

關鍵點:StrutsPrepareAndExecuteFilter 合併了舊版的 PrepareFilter + ExecuteFilter,負責配置載入與請求執行。

struts.xml 配置詳解

<?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>
    <!-- 常量配置 -->
    <constant name="struts.devMode" value="true"/>
    <constant name="struts.i18n.encoding" value="UTF-8"/>
    <constant name="struts.objectFactory" value="spring"/> <!-- 整合 Spring -->

    <!-- 包繼承:繼承 struts-default 獲得預設攔截器、結果類型 -->
    <package name="default" namespace="/" extends="struts-default">
        <!-- Action 配置 -->
        <action name="login" class="com.example.action.LoginAction" method="execute">
            <result name="success" type="dispatcher">/welcome.jsp</result>
            <result name="input">/login.jsp</result>
            <result name="error" type="redirect">/error.html</result>
        </action>

        <!-- 通配符映射 -->
        <action name="user/*" class="com.example.action.UserAction" method="{1}">
            <result name="list">/user/list.jsp</result>
            <result name="edit">/user/edit.jsp</result>
        </action>
    </package>
</struts>

Action 開發模式

1. POJO Action (推薦)

public class LoginAction {
    private String username;
    private String password;
    private UserService userService; // Spring 注入

    public String execute() {
        User user = userService.login(username, password);
        if (user != null) {
            return "success";
        }
        addActionError("帳號或密碼錯誤");
        return "input";
    }
    // getter/setter
}

2. 實作 Action 介面 (舊式)

public class LoginAction implements Action {
    public String execute() throws Exception { ... }
}

3. ModelDriven (表單綁定複雜物件)

public class UserAction implements ModelDriven<User> {
    private User user = new User();
    public User getModel() { return user; }
    public String save() { userService.save(user); return "success"; }
}

攔截器機制深度解析

預設攔截器棧

<interceptor-stack name="defaultStack">
    <interceptor-ref name="exception"/>
    <interceptor-ref name="alias"/>
    <interceptor-ref name="servletConfig"/>
    <interceptor-ref name="i18n"/>
    <interceptor-ref name="prepare"/>
    <interceptor-ref name="chain"/>
    <interceptor-ref name="modelDriven"/>
    <interceptor-ref name="fileUpload"/>
    <interceptor-ref name="checkbox"/>
    <interceptor-ref name="datetime"/>
    <interceptor-ref name="multiselect"/>
    <interceptor-ref name="staticParams"/>
    <interceptor-ref name="actionMappingParams"/>
    <interceptor-ref name="params"> <!-- 核心:參數注入 -->
        <param name="excludeParams">dojo\..*,^struts\..*,^session\..*,^request\..*,^application\..*,^servlet(Request|Response)\..*,parameters\..*</param>
    </interceptor-ref>
    <interceptor-ref name="conversionError"/>
    <interceptor-ref name="validation"> <!-- 驗證 -->
        <param name="excludeMethods">input,back,cancel,browse</param>
    </interceptor-ref>
    <interceptor-ref name="workflow"> <!-- 驗證失敗返回 input -->
        <param name="excludeMethods">input,back,cancel,browse</param>
    </interceptor-ref>
    <interceptor-ref name="debugging"/>
</interceptor-stack>

自定義攔截器

public class AuthInterceptor extends AbstractInterceptor {
    @Override
    public String intercept(ActionInvocation invocation) throws Exception {
        Map<String, Object> session = invocation.getInvocationContext().getSession();
        if (session.get("user") == null) {
            return "login"; // 重定向登入
        }
        return invocation.invoke(); // 繼續執行
    }
}
<interceptor name="auth" class="com.example.interceptor.AuthInterceptor"/>
<interceptor-stack name="secureStack">
    <interceptor-ref name="defaultStack"/>
    <interceptor-ref name="auth"/>
</interceptor-stack>
<action name="admin/*" class="...">
    <interceptor-ref name="secureStack"/>
    ...
</action>

結果類型

類型類別用途
dispatcher (預設)ServletDispatcherResult轉發到 JSP/HTML
redirectServletRedirectResult重定向 (瀏覽器地址變更)
redirectActionServletActionRedirectResult重定向到另一個 Action
streamStreamResult檔案下載、圖片輸出
jsonJSONResultREST API 返回 JSON (需 json-plugin)
freemarker/velocityFreeMarkerResult/VelocityResult模板引擎渲染
tilesTilesResultApache Tiles 佈局

OGNL 表達式核心語法

  • 屬性存取:user.name、user.address.city
  • 集合操作:users.{name} (投影)、users.?[age > 18] (過濾)、users.^[age > 18] (首個匹配)、users.$[age > 18] (最後匹配)
  • Map 操作:#session['key']、#request.key、#parameters.id
  • 方法呼叫:user.getFullName()、@com.example.Util@formatDate(date) (靜態方法)
  • 運算子:+ - * / %、== != < > <= >=、and or not、in (集合包含)

常見問題與解決

問題原因解決
參數無法注入1) 無 getter/setter 2) 類型轉換失敗 3) excludeParams 攔截檢查屬性封裝、自訂 TypeConverter、調整 params.interceptor excludeParams
檔案上傳失效缺少 fileUpload 攔截器、表單未設 enctype=multipart/form-data、超過最大尺寸確認 struts.multipart.maxSize、commons-fileupload 依賴
驗證不生效未實作 Validateable、方法名在 excludeMethods、驗證 XML 命名不符Action 類同名 -validation.xml、@Validations 註解
中文亂碼未設 struts.i18n.encoding、Tomcat URIEncoding、Filter 順序常量設 UTF-8、web.xml CharacterEncodingFilter 在最前
攔截器不執行攔截器棧引用錯誤、package 未 extends struts-default核對 interceptor-ref name、package extends

遷移建議:Struts 2 → Spring MVC

Struts 2Spring MVC
Action 類@Controller / @RestController
struts.xml@RequestMapping / 註解配置
攔截器HandlerInterceptor / Filter
OGNLSpEL / @RequestParam / @PathVariable
Result 類型ViewResolver / @ResponseBody / ResponseEntity
驗證Bean Validation (JSR-380) + @Valid
文件上傳MultipartFile + StandardServletMultipartResolver
國際化MessageSource + LocaleResolver

總結

Struts 2 以攔截器鏈、OGNL、POJO Action 為核心特色,曾風靡一時。但因安全漏洞頻發 (OGNL 注入)、社區活躍度下降、功能被 Spring MVC 完整覆蓋並超越,**新專案強烈建議直接使用 Spring Boot + Spring MVC**。維護舊專案時,掌握上述核心流程與配置可快速定位問題。

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