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

Spring MultiActionController 深度解析與改良方案(上)

     編輯:Java 相關知識

背景痛點

早期 Spring MVC 開發中,單一功能(增刪改查)常拆分為多個 Controller(AbstractController、SimpleFormController),導致類別爆炸、驗證邏輯重複、配置繁瑣。MultiActionController 參考 Struts DispatchAction 設計,允許一個 Controller 類別包含多個處理方法,透過 MethodNameResolver 將 URL 映射至方法。

標準用法範例

1. Controller 實作

public class SampleMultiMethodController extends MultiActionController {
    private SampleAction sampleAction; // 業務 Service

    public ModelAndView listUser(HttpServletRequest req, HttpServletResponse res) {
        List<UserInfoDTO> list = sampleAction.getUserInfoList();
        return new ModelAndView("userListView", "userInfoList", list);
    }

    public ModelAndView editUser(HttpServletRequest req, HttpServletResponse res) {
        String uid = RequestUtils.getStringParameter(req, "id");
        UserInfoDTO dto = (uid != null && !uid.isEmpty())
            ? sampleAction.getUserInfo(uid) : new UserInfoDTO();
        return new ModelAndView("userFormView", getCommandName(null), dto);
    }

    public ModelAndView saveUser(HttpServletRequest req, HttpServletResponse res,
                                 UserInfoDTO command) {
        ServletRequestDataBinder binder = new ServletRequestDataBinder(command);
        BindException errors = binder.getErrors();
        // 驗證邏輯...
        if (errors.hasErrors()) {
            return new ModelAndView("userFormView", errors.getModel());
        }
        sampleAction.saveUserInfo(command);
        return new ModelAndView("redirect:listUser.do");
    }

    public ModelAndView deleteUser(HttpServletRequest req, HttpServletResponse res) {
        sampleAction.deleteUserInfo(RequestUtils.getStringParameter(req, "id"));
        return new ModelAndView("redirect:listUser.do");
    }
    // getter/setter 略
}

2. 傳統 XML 配置(複雜)

<bean id="handlerMapping"
  class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
  <property name="defaultHandler" ref="sampleMultiMethodController"/>
</bean>

<bean id="sampleMultiMethodController"
  class="com.prs...SampleMultiMethodController">
  <property name="methodNameResolver">
    <bean class="org.springframework.web.servlet.mvc.multiaction.PropertiesMethodNameResolver">
      <property name="mappings">
        <props>
          <prop key="/listUser.do">listUser</prop>
          <prop key="/editUser.do">editUser</prop>
          <prop key="/saveUser.do">saveUser</prop>
        </props>
      </property>
    </bean>
  </property>
  <property name="sampleAction" ref="sampleAction"/>
</bean>

MultiActionController 三大缺點

  1. 配置繁瑣:需注入 MethodNameResolver,再定義 mappings 屬性,兩層嵌套。
  2. Bean 耦合度高:Controller 變更需同步修改 SimpleUrlHandlerMapping,違反單一職責。
  3. 資料綁定不彈性:命令物件名稱固定為 command,無法自訂語意化名稱(如 userInfoDTO)。

理想化改良構想

期望配置簡化為:

<bean name="sampleMultiMethodController"
  class="com.prs...SampleMultiMethodController">
  <property name="commandName" value="userInfoDTO"/>
  <property name="formView" value="userFormView"/>
  <property name="successView" value="redirect:listUser.do"/>
  <property name="urlMethodMappings">
    <props>
      <prop key="/listUser.do">listUser</prop>
      <prop key="/editUser.do">editUser</prop>
      <prop key="/saveUser.do">saveUser</prop>
      <prop key="/deleteUser.do">deleteUser</prop>
    </props>
  </property>
  <property name="sampleAction" ref="sampleAction"/>
</bean>

改良重點:
1. 將 URL→方法映射內移為 Controller 屬性 urlMethodMappings。
2. 新增 commandName、formView、successView 等屬性,支援彈性綁定與視圖。
3. 移除外部 MethodNameResolver 與 SimpleUrlHandlerMapping 耦合。

實作方向(下篇預告)

  • 自訂 MultiMethodController 介面,定義上述屬性契約。
  • 實作 MultiMethodControllerUrlHandlerMapping 掃描容器中所有實作該介面的 Bean,自動建立 URL 映射表。
  • Controller 基底類別實作 handleRequestInternal() 依映射分派方法、處理資料綁定與驗證。

結語

MultiActionController 雖解決類別爆炸,但配置複雜度轉移至 XML。將映射資訊內聚至 Controller 本身,並透過自訂 HandlerMapping 自動掃描,才是符合「慣例優於配置」的正確演進路徑。

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