Struts2通配符映射讓單個 Action 配置處理多個請求,配合動態方法調用(`!` 或 `method:` 前綴),大幅減少 `struts.xml` 配置量。本文通過用戶註冊/登錄/查詢完整業務流程,演示通配符配置、Action 類設計、結果頁面跳轉、參數接收與驗證的最佳實踐。
<package name="user" namespace="/user" extends="struts-default">
<!-- 匹配 user/user!register、user/user!login、user/user!query -->
<action name="user*" class="com.action.UserAction" method="{1}">
<result name="success">/success.jsp</result>
<result name="input">/register.jsp</result>
<result name="error">/error.jsp</result>
</action>
</package>
user* 匹配以 `user` 開頭的所有路徑{1} 捕獲 `*` 對應的字符串作為方法名(如 `register`、`login`)user_*_{1}_{2} → 方法名由 `{1}`、`{2}` 拼接public class UserAction extends ActionSupport {
private User user; // 自動封裝表單參數
private UserService userService;
// 註冊方法
public String register() {
if (userService.exists(user.getUsername())) {
addFieldError("username", "用戶名已存在");
return INPUT;
}
userService.save(user);
return SUCCESS;
}
// 登錄方法
public String login() {
User dbUser = userService.findByUsername(user.getUsername());
if (dbUser != null && dbUser.getPassword().equals(user.getPassword())) {
ActionContext.getContext().getSession().put("user", dbUser);
return SUCCESS;
}
addActionError("用戶名或密碼錯誤");
return ERROR;
}
// 查詢方法
public String query() {
List users = userService.findAll();
ActionContext.getContext().put("users", users);
return SUCCESS;
}
// Getter/Setter
}
<form action="${pageContext.request.contextPath}/user/user!register" method="post">
用戶名: <input name="user.username" /> <s:fielderror fieldName="user.username"/><br/>
密碼: <input type="password" name="user.password" /><br/>
郵箱: <input name="user.email" /><br/>
<input type="submit" value="註冊" />
</form>
<form action="${pageContext.request.contextPath}/user/user!login" method="post">
用戶名: <input name="user.username" /><br/>
密碼: <input type="password" name="user.password" /><br/>
<input type="submit" value="登錄" />
</form>
<s:actionerror />
<table border="1">
<tr><th>ID</th><th>用戶名</th><th>郵箱</th></tr>
<s:iterator value="#request.users">
<tr>
<td><s:property value="id"/></td>
<td><s:property value="username"/></td>
<td><s:property value="email"/></td>
</tr>
</s:iterator>
</table>
若不想用通配符,可開啟 DMI(Struts 2.3+ 默認關閉):
<constant name="struts.enable.DynamicMethodInvocation" value="true" />
URL 格式:/user/user!register.action 或 /user/user.action?method:register。不推薦:安全風險(任意方法調用)、REST 風格差、調試困難。
Struts2 通配符映射是「約定優於配置」的典型應用。一個 `