程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> Spring MVC中的MultiActionController用法詳解

Spring MVC中的MultiActionController用法詳解

編輯:關於JAVA

Spring MVC 中 Controller 的層次實在是多,有些眼花缭亂了 。在單個的基礎上,再新加兩三個叫做豐富,再多就未必是好事, 反而會令人縮手新聞片腳,無從定奪。多數 Controller 都是只完 成一個任務,不過也有一個像 Struts 的 DispatchAction 的那樣 的 Conntroller, org.springframework.web.servlet.mvc.multiaction.MultiActio nController,意即在一個 Controller 中處理多個動作,如同一 個業務的增、刪、改可以放在一起了。不至於增、刪、改各自為政 ,造成代碼混亂、重復難以維護。

本文中的 web.xml 的 org.springframework.web.servlet.DispatcherServlet 所處理的 url-pattern 是 *.html,如何搭建 Spring MVC 項目不細加說明 ,可參考我前面同系列的文章。

例如,下面的 UserController,有兩個簽名一樣的 updateUser() 和 deleteUser() 方法

public class UserController extends MultiActionController {
   public ModelAndView updateUser(HttpServletRequest request,
       HttpServletResponse response) {
     System.out.println("updateUser");//方便於跟蹤執 行了哪個方法
     return new ModelAndView ("userList","from","updateUser");
   }
   public ModelAndView deleteUser(HttpServletRequest request,
       HttpServletResponse response) {
     System.out.println("deleteUser");//方便於跟蹤執 行了哪個方法
     return new ModelAndView ("userList","from","deleteUser");
   }
}
public class UserController extends MultiActionController {
public ModelAndView updateUser(HttpServletRequest request,
  HttpServletResponse response) {
  System.out.println("updateUser");//方便於跟蹤執行了哪 個方法
  return new ModelAndView ("userList","from","updateUser");
}
public ModelAndView deleteUser(HttpServletRequest request,
  HttpServletResponse response) {
  System.out.println("deleteUser");//方便於跟蹤執行了哪 個方法
  return new ModelAndView ("userList","from","deleteUser");
}
}

用過 Struts 的 DispatchAction 的都知道,是通過 http://.../userAction.do?method=updateUser 的方式來指定執 行哪個方法。那 Spring MVC中是如何定位到所需方法上呢?

Spring MVC 除了有一個叫做 HandlerMapping(把 URL 解析到 Controller) 的東西,還要把操作進一步解析到方法名上,即要找 到的 Controller 上的哪個方法並執行之。缺省的方法名解析器是 InternalPathMethodNameResolver,它根據 URL 樣式解析方法名 。

在缺省的 BeanNameUrlHandlerMapping 和缺省的 InternalPathMethodNameResolver 協調之下,Bean 上下文可以這 樣配置:

<bean name="/updateUser.html" class="com.unmi.UserController"/>
<bean name="/deleteUser.html" class="com.unmi.UserController"/>
<bean name="/updateUser.html" class="com.unmi.UserController"/>
<bean name="/deleteUser.html" class="com.unmi.UserController"/>

這樣分別通過下面的 URL 就能執行到正確的方法上去了:

http://.../updateUser.html -- 將被 UserController.updateUser() 處理

http://.../deleteUser.html  --  將被 UserController.deleteUser() 處理

但是,你應該注意到了,上面的 com.unmi.UserController 配 置了兩次,一來礙眼、二來原來只要 Singleton 的 UserController 實例不再是那麼回事了。所以要引入 SimpleUrlHandlerMapping 對 Bean 配置進一步緊湊一下:

<bean id="userController" class="com.unmi.UserController"/>
<bean id="simpleUrlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHa ndlerMapping">
   <property name="mappings">
     <props>
       <prop key="/updateUser.html">userController</prop>
       <prop key="/deleteUser.html">userController</prop>
     </props>
   </property>
</bean>
<bean id="userController" class="com.unmi.UserController"/>
<bean id="simpleUrlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHa ndlerMapping">
  <property name="mappings">
  <props>
   <prop key="/updateUser.html">userController</prop>
   <prop key="/deleteUser.html">userController</prop>
  </props>
  </property>
</bean>

說是緊湊,倒不如說 Bean 配置復雜了,反正不用配置兩個相 同的 UserController 實例了。還是通過上面那兩個 URL 來訪問 執行到相應的方法。

除了缺省的方法名解析器 InternalPathMethodNameResolver( 注意了,Spring 中缺省的 XXX 很多用 InternalXXX 的命名),還 有兩種其他類型的方法名解析器:

·ParameterMethodNameResolver -- 根據請求中的參數解析執 行方法名,相當於 Struts 的 DispathAction

·PropertiesMethodNameResolver -- 根據查詢一個 key/value 列表解析執行方法名,相當於 Struts 的 MappingDispatchAction(用得很少)

下面逐一介紹使用上面兩種方法名解析器時的 Bean 配置及相 應訪問的 URL。

使用 ParameterMethodNameResolver 時的 Bean 配置(為簡單 起見,又用回了缺省的 HandlerMapping):

<bean name="/user.html" class="com.unmi.UserController">
   <property name="methodNameResolver">
     <ref bean="methodNameResolver"/>
   </property>
</bean>
<bean name="methodNameResolver" class="org.springframework.web.servlet.mvc.multiaction.Par ameterMethodNameResolver">
   <property name="paramName">
     <value>method</value>
   </property>
</bean>
<bean name="/user.html" class="com.unmi.UserController">
  <property name="methodNameResolver">
  <ref bean="methodNameResolver"/>
  </property>
</bean>
<bean name="methodNameResolver" class="org.springframework.web.servlet.mvc.multiaction.Par ameterMethodNameResolver">
  <property name="paramName">
  <value>method</value>
  </property>
</bean>

這時候分別用下面的 URL 就能訪問到相應的方法

http://.../user.html?method=updateUser -- 將被 UserController.updateUser() 處理

http://.../user.html?method=deleteUser -- 將被 UserController.deleteUser() 處理

通過參數的方式使得 HTML 表單表現用戶選擇成為可能,例如 把 method 參數可放在一個下拉框或隱藏域中。

使用 PropertiesMethodNameResolver 時的 Bean 配置

<bean id="userController" class="com.unmi.UserController" />
<bean id="simpleUrlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHa ndlerMapping">
   <property name="mappings">
     <props>
       <prop key="/updateUser.html">userController</prop>
       <prop key="/deleteUser.html">userController</prop>
     </props>
   </property>
</bean>
<bean id="methodNameResolver"  class="org.springframework.web.servlet.mvc.multiaction.Pro pertiesMethodNameResolver">
   <property name="mappings">
     <props>
       <prop key="/updateUser.html">updateUser</prop>
       <prop key="/deleteUser.html">deleteUser</prop>
     </props>
   </property>
</bean>
<bean id="userController" class="com.unmi.UserController" />
<bean id="simpleUrlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHa ndlerMapping">
  <property name="mappings">
  <props>
   <prop key="/updateUser.html">userController</prop>
   <prop key="/deleteUser.html">userController</prop>
  </props>
  </property>
</bean>
<bean id="methodNameResolver"class="org.springframework.web.serv let.mvc.multiaction.PropertiesMethodNameResolver">
  <property name="mappings">
  <props>
   <prop key="/updateUser.html">updateUser</prop>
   <prop key="/deleteUser.html">deleteUser</prop>
  </props>
  </property>
</bean>

這種配置有點復雜,PropertiesMethodNameResolver 不僅與 SimpleUrlHandlerMapping 相仿又有重疊,而且必須把 SimpleUrlHandlerMapping 拉進來,無法使用默認的 HandlerMapping。從上面的配置我們可以明顯的看出 HandlerMapping 和 MethodNameResolver 不同職責了,一個是定 位 Controller,一個是定位 Method。

這時候分別用下面的 URL 來訪問到相應 Controller 的方法

http://.../updateUser.html -- 將被 UserController.updateUser() 處理

http://.../deleteUser.html  --  將被 UserController.deleteUser() 處理

這裡的 URL 恰巧和使用 InternalPathMethodNameResolver  時是一樣的,但一定要理解其實他們的機制是一樣的。

PropertiesMethodNameResolver 把事性搞這麼復雜,被譽為最 復雜的方法名解析器。可我還真看不出它還有什麼獨到之處,或值 得一用的理由,同時也不難理解 Struts 的 MappingDispatchAction 鮮為人知的緣由了。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved