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

Struts 核心控制器深度解析:DispatchAction 多方法分發機制原理與實戰

     編輯:Java 相關知識

從 Action 到 DispatchAction 的演進

標準 Action 類僅提供單一 execute() 方法,導致「一個業務操作對應一個 Action 類」,類爆炸嚴重。org.apache.struts.actions.DispatchAction 通過「方法分發」機制,允許在一個 Action 類中定義多個業務方法,根據請求參數動態調用,極大減少類數量。

DispatchAction 核心原理

  • 繼承 Action,覆寫 execute()。
  • 內部 execute() 邏輯:從請求中獲取 parameter 屬性指定的參數值 (如 command=list) → 以該值為方法名,通過反射查找對應方法 → 調用 method(mapping, form, request, response) → 返回 ActionForward。
  • 方法簽名必須與 execute 一致:public ActionForward xxx(ActionMapping, ActionForm, HttpServletRequest, HttpServletResponse)。

實戰:用戶管理 CRUD 整合

1. JSP 請求發起

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

2. 統一 Action 類

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");
    }
}

3. struts-config.xml 關鍵配置

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

核心限制與進階替代方案

限制

  1. 僅支持 GET 請求分發:依賴 URL 參數 (?command=xxx);不支持 POST 表單提交分發,因表單提交時參數在 Body 中,DispatchAction 默認只從 Query String 獲取 parameter。
  2. 方法名直接暴露在 URL 中,存在安全風險 (需配合權限攔截器)。

進階替代:LookupDispatchAction

  • 通過 getKeyMethodMap() 返回 Map<String, String>,Key 為國際化消息鍵,Value 為方法名。
  • JSP 使用 <html:submit property="action"><bean:message key="button.save"/></html:submit>,提交值為國際化文本。
  • 框架根據提交值匹配 Map Key,調用對應方法,完美支持 POST 表單分發並隱藏方法名。

現代替代:Spring MVC

@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 框架設計的進步。

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