標準 Action 類僅提供單一 execute() 方法,導致「一個業務操作對應一個 Action 類」,類爆炸嚴重。org.apache.struts.actions.DispatchAction 通過「方法分發」機制,允許在一個 Action 類中定義多個業務方法,根據請求參數動態調用,極大減少類數量。
Action,覆寫 execute()。execute() 邏輯:從請求中獲取 parameter 屬性指定的參數值 (如 command=list) → 以該值為方法名,通過反射查找對應方法 → 調用 method(mapping, form, request, response) → 返回 ActionForward。execute 一致:public ActionForward xxx(ActionMapping, ActionForm, HttpServletRequest, HttpServletResponse)。<a href="user/user_maint.do?command=list">用戶列表</a>
<a href="user/user_maint.do?command=add">新增用戶</a>
<form action="user/user_maint.do?command=save" method="post">...</form>
public class UserAction extends DispatchAction {
// 列表查詢
public ActionForward list(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
List userList = UserManager.getInstance().findAllUserList();
request.setAttribute("userlist", userList);
return mapping.findForward("list_success");
}
// 新增/保存
public ActionForward save(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
UserActionForm uaf = (UserActionForm) form;
User user = new User();
BeanUtils.copyProperties(user, uaf); // 表單數據自動填充實體
user.setCreateDate(new Date());
UserManager.getInstance().addUser(user);
return mapping.findForward("add_success");
}
// 刪除 (批量)
public ActionForward del(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
UserActionForm uaf = (UserActionForm) form;
String[] userIds = uaf.getSelectFlag(); // 複選框數組
UserManager.getInstance().deleteUsers(userIds);
return mapping.findForward("del_success");
}
// 修改
public ActionForward modify(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
UserActionForm uaf = (UserActionForm) form;
User user = new User();
BeanUtils.copyProperties(user, uaf);
UserManager.getInstance().modifyUser(user);
return mapping.findForward("modify_success");
}
// 查詢詳情
public ActionForward find(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
UserActionForm uaf = (UserActionForm) form;
User user = UserManager.getInstance().findUserById(uaf.getUserId());
request.setAttribute("user", user);
return mapping.findForward("find_success");
}
}
<action path="/user/user_maint"
type="com.example.action.UserAction"
name="userForm"
scope="request"
parameter="command" > <!-- 核心:指定分發參數名 -->
<forward name="list_success" path="/user/user_list.jsp"/>
<forward name="add_success" path="/user/user_maint.do?command=list" redirect="true"/>
<forward name="del_success" path="/user/user_maint.do?command=list" redirect="true"/>
<forward name="modify_success" path="/user/user_maint.do?command=list" redirect="true"/>
<forward name="find_success" path="/user/user_modify.jsp"/>
</action>
?command=xxx);不支持 POST 表單提交分發,因表單提交時參數在 Body 中,DispatchAction 默認只從 Query String 獲取 parameter。getKeyMethodMap() 返回 Map<String, String>,Key 為國際化消息鍵,Value 為方法名。<html:submit property="action"><bean:message key="button.save"/></html:submit>,提交值為國際化文本。@Controller
@RequestMapping("/user")
public class UserController {
@GetMapping("/list") public String list(Model model) { ... }
@PostMapping("/save") public String save(@ModelAttribute UserForm form) { ... }
@PostMapping("/delete") public String delete(@RequestParam("ids") String[] ids) { ... }
}
Spring MVC 以註解式映射、方法級參數綁定、RESTful 風格徹底解決了 DispatchAction 的所有痛點。
DispatchAction 是 Struts 1.x 時代解決「Action 類爆炸」的經典方案,基於「配置參數 + 反射調用」的簡潔設計思想值得借鑒。理解其原理與局限,有助於深刻體會現代 MVC 框架設計的進步。