Struts 2 作為經典的 MVC 框架,雖然在新項目中較少使用,但在維護老項目時仍不可避免。本文記錄完整的開發環境搭建、登錄功能實現,並總結實戰中遇到的高頻 404 錯誤及解決方案。
Struts 2.2+ 所需 JAR 包(放入 WEB-INF/lib 或配置 Build Path):
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
注意:Struts 2.3+ 版本 filter-class 可能為 org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter,請根據實際版本調整。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"https://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<package name="main" extends="struts-default">
<!-- Action 配置將在這裡編寫 -->
</package>
</struts>
文件必須放在 src 目錄下,命名為 struts.xml(小寫)。
<form action="<%=request.getContextPath()%>/login" method="post">
賬號: <input type="text" name="username" /><br/>
密碼: <input type="password" name="userpwd" /><br/>
<input type="submit" value="提交"/>
</form>
使用 request.getContextPath() 解決相對路徑問題,確保表單提交地址正確。
package com.weiyang.action;
import com.opensymphony.xwork2.ActionSupport;
public class LoginAction extends ActionSupport {
private String username;
private String userpwd;
// Getter/Setter 省略...
@Override
public String execute() {
if ("admin".equalsIgnoreCase(username) && "123456".equalsIgnoreCase(userpwd)) {
return SUCCESS;
}
return ERROR;
}
}
關鍵點:屬性名(username、userpwd)必須與 JSP 表單 name 屬性完全一致,Struts 2 通過反射自動注入。
<action name="login" class="com.weiyang.action.LoginAction">
<result name="success">/WEB-INF/success.jsp</result>
<result name="error">/WEB-INF/error.jsp</result>
</action>
result 路徑建議使用絕對路徑(以 / 開頭),避免因 JSP 所在目錄不同導致跳轉失敗。
| 現象 | 可能原因 | 解決方案 |
|---|---|---|
配置 struts.action.extension 後訪問 404 | 擴展名限制導致無後綴 URL 無法匹配 | 註釋掉或正確配置 <constant name="struts.action.extension" value="action,,do" />(注意空字符串允許無後綴) |
| 表單 action 未使用項目路徑 | action="login" 而非 action="/login" 或 <%=request.getContextPath()%>/login | 統一使用絕對路徑或項目上下文路徑 |
| JSP 放在子目錄(如 Page/) | 相對路徑解析錯誤 | 表單 action 必須包含完整路徑上下文 |
<include file="login.xml"/> 導致 404 | 模塊化配置文件路徑或 DTD 聲明問題 | 檢查 include 文件路徑、確保 login.xml 獨立有效、DTD 聲明正確 |
| Action 類包名/類名拼寫錯誤 | struts.xml 中 class 屬性與實際不符 | 仔細核對包名大小寫、類名拼寫 |
隨著功能增長,建議按業務模塊拆分配置:
<!-- struts.xml -->
<include file="login.xml"/>
<include file="user.xml"/>
<include file="product.xml"/>
每個子配置文件保持相同的 DTD 聲明與 <struts> 根元素,package name 應唯一且語義化。
index.jsp,提交表單到 /loginweb.xml 中的 StrutsPrepareAndExecuteFilter 攔截請求struts.xml 找到 name="login" 的 Action 配置LoginAction,自動注入表單參數execute() 方法,返回 SUCCESS 或 ERROR