4.15、MultiActionController
之前學過的控制器如AbstractCommandController、SimpleFormController等一般對應一個功能處理方法(如新增),如果我要實現比如最簡單的用戶增刪改查(CRUD Create-Read-Update-Delete),那該怎麼辦呢?
4.15.1 解決方案
1、每一個功能對應一個控制器,如果是CRUD則需要四個控制器,但這樣我們的控制器會暴增,肯定不可取;
2、使用Spring Web MVC提供的MultiActionController,用於支持在一個控制器裏添加多個功能處理方法,即將多個請求的處理方法放置到一個控制器裏,這種方式不錯。
4.15.2 問題
1、 MultiActionController如何將不同的請求映射不同的請求的功能處理方法呢?
Spring Web MVC提供了MethodNameResolver(方法名解析器)用於解析當前請求到需要執行的功能處理方法的方法名。默認使用InternalPathMethodNameResolver實現類,另外還提供了ParameterMethodNameResolver和PropertiesMethodNameResolver,當然我們也可以自己來實現,稍候我們仔細研究下它們是如何工作的。
2、那我們的功能處理方法應該怎麼寫呢?
public (ModelAndView | Map | String | void) actionName(HttpServletRequest request, HttpServletResponse response, [,HttpSession session] [,AnyObject]);
哦,原來如此,我們只需要按照如上格式寫我們的功能處理方法即可;此處需要注意一下幾點:
1、返回值:即模型和視圖部分;
ModelAndView:模型和視圖部分,之前已經見過了;
Map:只返回模型數據,邏輯視圖名會根據RequestToViewNameTranslator實現類來計算,稍候討論;
String:只返回邏輯視圖名;
void:表示該功能方法直接寫出response響應(如果其他返回值類型(如Map)返回null則和void進行相同的處理);
2、actionName:功能方法名字;由methodNameResolver根據請求信息解析功能方法名,通過反射調用;
3、形參列表:順序固定,“[]”表示可選,我們來看看幾個示例吧:
//表示到新增頁面
public ModelAndView toAdd(HttpServletRequest request, HttpServletResponse response);
//表示新增表單提交,在最後可以帶着命令對象
public ModelAndView add(HttpServletRequest request, HttpServletResponse response, UserModel user);
//列表,但只返回模型數據,視圖名會通過RequestToViewNameTranslator實現來計算
public Map list(HttpServletRequest request, HttpServletResponse response);
//文件下載,返回值類型爲void,表示該功能方法直接寫響應
public void fileDownload(HttpServletRequest request, HttpServletResponse response)
//第三個參數可以是session
public ModelAndView sessionWith(HttpServletRequest request, HttpServletResponse response, HttpSession session);
//如果第三個參數是session,那麼第四個可以是命令對象,順序必須是如下順序
public void sessionAndCommandWith(HttpServletRequest request, HttpServletResponse response, HttpSession session, UserModel user)
4、異常處理方法,MultiActionController提供了簡單的異常處理,即在請求的功能處理過程中遇到異常會交給異常處理方法進行處理,式如下所示:
public ModelAndView anyMeaningfulName(HttpServletRequest request, HttpServletResponse response, ExceptionClass exception)
MultiActionController會使用最接近的異常類型來匹配對應的異常處理方法,示例如下所示:
//處理PayException
public ModelAndView processPayException(HttpServletRequest request, HttpServletResponse response, PayException ex)
//處理Exception
public ModelAndView processException(HttpServletRequest request, HttpServletResponse response, Exception ex)
4.15.3 MultiActionController類實現
類定義:public class MultiActionController extends AbstractController implements LastModified ,繼承了AbstractController,並實現了LastModified接口,默認返回-1;
核心屬性:
delegate:功能處理的委託對象,即我們要調用請求處理方法所在的對象,默認是this;
methodNameResolver:功能處理方法名解析器,即根據請求信息來解析需要執行的delegate的功能處理方法的方法名。
核心方法:
經典介紹:
源碼結構
更多詳細源碼參考來源:http://minglisoft.cn/technology
Java代碼
- //判斷方法是否是功能處理方法
- private boolean isHandlerMethod(Method method) {
- //得到方法返回值類型
- Class returnType = method.getReturnType();
- //返回值類型必須是ModelAndView、Map、String、void中的一種,否則不是功能處理方法
- if (ModelAndView.class.equals(returnType) || Map.class.equals(returnType) || String.class.equals(returnType) ||
- void.class.equals(returnType)) {
- Class[] parameterTypes = method.getParameterTypes();
- //功能處理方法參數個數必須>=2,且第一個是HttpServletRequest類型、第二個是HttpServletResponse
- //且不能Controller接口的handleRequest(HttpServletRequest request, HttpServletResponse response),這個方法是由系統調用
- return (parameterTypes.length >= 2 &&
- HttpServletRequest.class.equals(parameterTypes[0]) &&
- HttpServletResponse.class.equals(parameterTypes[1]) &&
- !("handleRequest".equals(method.getName()) && parameterTypes.length == 2));
- }
- return false;
- }
歡迎大家一起學習研究相關技術願意瞭解框架技術或者源碼的朋友直接加求求(企鵝):2042849237
更多詳細源碼參考來源:http://minglisoft.cn/technology