Struts 2 以 WebWork 為核心,融合 Struts 1 優點,構建了基於**攔截器模式**的 MVC 框架。本文通過**最小化 Hello World** 完整演示:環境搭建、Action 實現三種方式、配置文件詳解、請求處理流程、結果類型、常見錯誤排查。
地址:https://struts.apache.org/download.cgi
建議下載 **`struts-
<properties>
<struts2.version>2.5.30</struts2.version> <!-- 當前穩定版 -->
</properties>
<dependencies>
<!-- 核心 -->
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-core</artifactId>
<version>${struts2.version}</version>
</dependency>
<!-- JSON 插件 (REST API 必備) -->
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-json-plugin</artifactId>
<version>${struts2.version}</version>
</dependency>
<!-- JSP 標簽庫 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
| 方式 | 代碼示例 | 優缺點 |
|---|---|---|
| 1. 普通 POJO | public class UserAction {
private String name;
public String execute() { return "success"; }
// Getter/Setter
} | 最簡潔,推薦 |
| 2. 實現 Action 接口 | public class UserAction implements Action {
public String execute() { return SUCCESS; }
} | 強制規範,可用常量 SUCCESS/ERROR/INPUT/LOGIN/NONE |
| 3. 繼承 ActionSupport (最常用) | public class UserAction extends ActionSupport {
private String name;
public String execute() {
addActionMessage("歡迎 " + name);
return SUCCESS;
}
} | **提供驗證、國際化、ActionMessage 等豐富基礎功能**,實戰首選 |
<web-app xmlns="https://xmlns.jcp.org/xml/ns/javaee" version="3.1">
<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>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
關鍵點: Struts 2.5+ 使用 `StrutsPrepareAndExecuteFilter` (單一過濾器),舊版為 `StrutsPrepareAndExecuteFilter` (ng 包) 或雙過濾器。
<?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.enable.DynamicMethodInvocation" value="false" />
<package name="default" namespace="/" extends="struts-default">
<!-- 全局結果 -->
<global-results>
<result name="error">/error.jsp</result>
</global-results>
<global-exception-mappings>
<exception-mapping exception="java.lang.Exception" result="error"/>
</global-exception-mappings>
<!-- Action 定義 -->
<action name="userAction" class="com.able.action.UserAction" method="execute">
<result name="success">/index.jsp</result>
<result name="input">/register.jsp</result> <!-- 驗證失敗返回 -->
</action>
<action name="login" class="com.able.action.LoginFieldAction">
<result name="success">/index.jsp</result>
</action>
</package>
</struts>
package com.able.action;
import com.opensymphony.xwork2.ActionSupport;
public class UserAction extends ActionSupport {
private String name;
private String message;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getMessage() { return message; }
public void setMessage(String message) { this.message = message; }
public String execute() {
System.out.println("接收參數 name:" + name);
message = "Hello World, " + name;
return "success"; // 對應 result name="success"
}
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head><title>Struts2 Hello World</title></head>
<body>
<s:form action="userAction">
<s:textfield name="name" label="用戶名" />
<s:submit value="提交" />
</s:form>
<div>
<s:property value="message" /> <!-- 輸出 Action 中的 message 屬性 -->
</div>
<div>
通過屬性傳值:<br/>
<s:property value="username" /><br/>
<s:property value="password" />
</div>
<div>
通過 JavaBean (ModelDriven) 獲取:<br/>
<s:property value="user.username" /><br/>
<s:property value="user.password" />
</div>
</body>
</html>
StrutsPrepareAndExecuteFilter 攔截請求,**Prepare 階段**查找 ActionMapping,**Execute 階段**執行攔截器鏈與 Action。| 現象 | 原因 | 解決 |
|---|---|---|
| 404 無法找到 Action | namespace/action name 不匹配、struts.xml 未放在 classpath 根目錄 | 檢查 namespace="/", action name="userAction",請求路徑 /userAction | 參數無法封裝 (null) | 表單字段 name 與 Action 屬性名不一致、缺少 Getter/Setter | 嚴格對應 name="username" ↔ setUsername() |
| JSP 標簽庫報錯 | 缺少 jstl 依賴、taglib uri 錯誤 | 引入 jstl:1.2,uri="/struts-tags" |
| 開發模式不生效 | struts.devMode=true 但修改配置未重啟 | devMode 僅熱加載配置文件,Java 類修改仍需重啟或熱部署 |
Struts 2 以**攔截器鏈**替代傳統基類繼承,**POJO Action** 降低侵入性,**OGNL** 提供強大表達能力。
掌握:web.xml Filter → struts.xml Package/Action/Result → POJO Action → JSP + Struts Tags這條主線,即可快速上手。
下一篇將深入:**攔截器棧定制、驗證框架、文件上傳、類型轉換、REST 插件、約定優於配置**。