黄色网页视频 I 影音先锋日日狠狠久久 I 秋霞午夜毛片 I 秋霞一二三区 I 国产成人片无码视频 I 国产 精品 自在自线 I av免费观看网站 I 日本精品久久久久中文字幕5 I 91看视频 I 看全色黄大色黄女片18 I 精品不卡一区 I 亚洲最新精品 I 欧美 激情 在线 I 人妻少妇精品久久 I 国产99视频精品免费专区 I 欧美影院 I 欧美精品在欧美一区二区少妇 I av大片网站 I 国产精品黄色片 I 888久久 I 狠狠干最新 I 看看黄色一级片 I 黄色精品久久 I 三级av在线 I 69色综合 I 国产日韩欧美91 I 亚洲精品偷拍 I 激情小说亚洲图片 I 久久国产视频精品 I 国产综合精品一区二区三区 I 色婷婷国产 I 最新成人av在线 I 国产私拍精品 I 日韩成人影音 I 日日夜夜天天综合

Spring架構(gòu)增強MultiActionController(上)

系統(tǒng) 2162 0

在使用Spring提供的控制器時,AbstractController和SimpleFormController是應(yīng)用得最多的。AbstractController是最基本的Controller,可以給予用戶最大的靈活性。SimpleFormController則用于典型的表單編輯和提交。在一個需要增,刪,改,查的需求中,增加和修改擴展SimpleFormController完成,刪除和查詢則擴展AbstractController完成。

??? 但是像上面那樣完成某一業(yè)務(wù)對象的增,刪,改,查,都屬于一類相關(guān)的業(yè)務(wù)。把一類相關(guān)的操作分布到不同的類去完成,違返“高內(nèi)聚”的設(shè)計原則。這樣四個業(yè)務(wù)操作需要四個類來完成,造成太多的類文件,難以維護和配置。

??? 所以Spring借鑒Struts的DispatchAction提供了類似功能的MultiActionController。可以實現(xiàn)不同的請求路徑對應(yīng)MultiActionController中的不同方法,這樣就可以把相關(guān)的操作都在一個類的相關(guān)方法中完成。這樣使得這個類具有“高內(nèi)聚”,也利于系統(tǒng)的維護,還避免了重復代碼。增加和修改操作的數(shù)據(jù)驗證邏輯是很相似的,使用MultiActionController后就可以讓增加和修改操作共用一段數(shù)據(jù)驗證邏輯代碼。

??? 1. 使用MultiActionController

??? MultiActionController會使不同的請求映射為不同方法,這里是一個實現(xiàn)用戶信息增刪改查的例子:

??? 1.1 SampleMultiMethodController實現(xiàn)

public class SampleMultiMethodController extends MultiActionController ... {
?
// 用戶信息列表view
? private static final String userInfoListView = " ehld.sample.getuserinfolist " ;
?
// 用戶信息編輯view
? private static final String userFormView = " ehld.sample.userForm " ;
?
// 提交成功后顯示的view
? private static final String userSuccessView = " redirect:ehld.sample.getuserinfolist.do " ;
?
// 用戶信息列表key值
? private static final String userInfoListKey = " userInfoList " ;
?
// userid
? private final String userIdParam = " id " ;
?
// 定義業(yè)務(wù)對象
? private SampleAction sampleAction;
?
public SampleAction getSampleAction() ... {
???????
return sampleAction;
? }

?
public void setSampleAction(SampleAction sampleAction) ... {
???
this .sampleAction = sampleAction;
? }


?
/**/ /* *
?? * 功能:獲得所有的用戶信息<br>
?
*/

?
public ModelAndView listUser(HttpServletRequest request,
HttpServletResponse response) throws Exception
... {
???? List userInfoList
= this .sampleAction.getUserInfoList();
???? ModelAndView mav
= new ModelAndView(userInfoListView);
???? mav.addObject(
this .userInfoListKey,userInfoList);
????
return mav;
? }


?
/**/ /* *
?? * 功能:編輯用戶信息<br>
?
*/

?
public ModelAndView edtiUser(HttpServletRequest request,
??????????? HttpServletResponse response) throws Exception
... {
???? String uid
= RequestUtils.getStringParameter(request, userIdParam);
???? UserInfoDTO userInfo
= null ;
????
if ( ! "" .equals(uid)) ... {
??? userInfo
= this .sampleAction.getUserInfo(uid);
???? }

????
if (userInfo == null ) ... {
??? userInfo
= new UserInfoDTO();
???? }

???? ModelAndView mav
= new ModelAndView( this .userFormView, this
??????????????? .getCommandName(
null ), userInfo);
????
return mav;
? }

?
/**/ /* *
?? * 功能:保存修改或新增的用戶信息<br>
?? *檢查從頁面bind的對象,如果userId或userName為空則返回原來的form頁面;
否則進行保存用戶信息操作,返回
*成功頁面
?
*/

public ModelAndView saveUser(HttpServletRequest request,
??????????? HttpServletResponse response, UserInfoDTO command) throws Exception
... {
?????? UserInfoDTO user
= (UserInfoDTO) command;
??? ServletRequestDataBinder binder
= new ServletRequestDataBinder(command,
??????????????? getCommandName(command));
??? BindException errors
= binder.getErrors();
??? ModelAndView mav
= null ;
???
if (user.getUserID() == null || "" .equals(user.getUserID())) ... {
??????? errors.rejectValue(
" userID " , " userIdNull " , " 用戶id不能為空 " );
??? }


???
if (user.getUserName() == null || "" .equals(user.getUserName())) ... {
??????? errors.reject(
" userNameNull " , " 用戶名不能為空 " );
??? }

???
if (errors.hasErrors()) ... {
?????? mav
= new ModelAndView( this .userFormView, errors.getModel());
??? }
else ... {

??????
this .sampleAction.saveUserInfo(user); // 保存用戶信息
?????? mav = new ModelAndView( this .userSuccessView);
??? }

???????
return mav;
}

?
/**/ /* *
?? * 功能:刪除用戶信息<br>
?
*/

public ModelAndView deleteUser(HttpServletRequest request,
??????????? HttpServletResponse response) throws Exception
... {
????? String uid
= RequestUtils.getStringParameter(request, userIdParam);
????? UserInfoDTO user
= new UserInfoDTO();
????? user.setUserID(uid);
?????
this .sampleAction.deleteUserInfo(user);
????? ModelAndView mav
= new ModelAndView( this .userSuccessView);
?????
return mav;
}

}

1.2 web-context配置

<!-- 把sampleMultiMethodController所有的請求映射到SimpleUrlHandlerMapping -->
< bean id = " handlerMapping "
class = " org.springframework.web.servlet.handler.SimpleUrlHandlerMapping " >
< property name = " defaultHandler " ref = " sampleMultiMethodController " />
</ bean >

<!-- 集增,刪,改,查操作到一個類的controller -->
< bean id = " sampleMultiMethodController "
class = " com.prs.application.ehld.sample.web.controller.SampleMultiMethodController " >
< property name = " methodNameResolver " >
< bean
class = " org.springframework.web.servlet.mvc.multiaction.PropertiesMethodNameResolver " >
< property name = " mappings " >
< props >
< prop key = " /ehld.sample.getuserinfolist.do " > listUser </ prop >
< prop key = " /ehld.sample.edituserinfo.do " > edtiUser </ prop >
< prop key = " /ehld.sample.saveuserinfo.do " > saveUser </ prop >
</ props >
</ property >
</ bean >
</ property >
< property name = " sampleAction "
ref = " com.prs.application.ehld.sample.biz.action.sampleAction " ></ property >
</ bean >
?

2. MultiActionController的缺點

??? MultiActionController把相關(guān)的業(yè)務(wù)方法集中在一個類中進行處理,減少控制類的數(shù)量。方便于系統(tǒng)的維護,可以重用相關(guān)的邏輯代碼,提高代碼的重用,同時也減少bean的配置。有太多的bean配置可以說是Spring 的一個暇疵。Spring提供IOC,讓我們靈活的控制bean的依賴。同時我們需要去維護太多的bean配置,Spring項目中很大程度上都在爛用xml 配置文件,這很不利于團隊開發(fā)和系統(tǒng)的后期維護。MultiActionController也不例外。

??? 1. multiActionController的配置相對復雜。MultiActionController需要注入一個MethodNameResolver對象,再通過MethodNameResolver的mappings屬性來提供請求與方法之間的映射。這樣的配置是復雜的和難以理解的。使用Spring框架的確很靈活,但是有時這種過分的靈活反而增加了系統(tǒng)的復雜度。

??? 2. multiActionController配置涉及的bean過多。除了自身的bean定義外,還需要把所有的映射配置到一個UrlHandlerMapping中去。這樣除了維護multiActionController的自身的bean定義外,還需要維護UrlHandlerMapping的定義。

???? 筆者十分反對這種具有連帶性的配置,一個bean的屬性改變會造成對別一個bean屬性的改變。這樣增加了系統(tǒng)的復雜度,和維護成本。所以必須提供一種默認的實現(xiàn),讓bean之間的依賴,不要造成bean屬性之間的依賴。MultiActionController在這方面表示得十分不好。

??? 3. 數(shù)據(jù)綁定支持不好。SimpleFormController專門用來支持編輯和表單提效的,它支持數(shù)據(jù)綁定,在這方面做得很好。可以把jsp頁面的字段值綁定為某一對象(Command)。可以自定義command的名稱。雖然MultiActionController也支持數(shù)據(jù)綁定,但是它并不支持自定義command的名稱。它默認的comamnd名稱為”command”。這也是不便于維護的,對象應(yīng)該有一個代表自身含義的名字。如果所有頁面的綁定對象都以”command”作為名字,那將難以理解。MultiActionController支持數(shù)據(jù)綁定的方法參見上面例子的saveUser方法。

1

3. 理想的MultiActionController構(gòu)想

??? 一個理想的MultActionController應(yīng)該配置簡單明了,并且無需要在多個地方進行配置。 應(yīng)該支持對綁定對象自定義名稱。

< bean name = " sampleMultiMethodController "
class = " com.prs.application.ehld.sample.web.controller.SampleMultiMethodController " >
< property name = " commandName " value = " userInfoDTO " />
< property name = " formView " value = " ehld.sample.userForm " />
< property name = " successView " value = " redirect:ehld.sample.getuserinfolist.do " />
< property name = " urlMethodmappings " >
< props >
<!-- 顯示用戶信息列表 -->
< prop key = " /ehld.sample.getuserinfolist.do " > listUser </ prop >
<!-- 編輯用戶信息 -->
< prop key = " /ehld.sample.edituserinfo.do " > edtiUser </ prop >
<!-- 保存用戶信息 -->
< prop key = " /ehld.sample.saveuserinfo.do " > saveUser </ prop >
</ props >
</ property >
< property name = " sampleAction "
ref = " com.prs.application.ehld.sample.biz.action.sampleAction " ></ property >
</ bean >

??? 上面是一個更讓人能夠理解的配置。

??? 1.把請求與具體方法之間的映射作為MultiActionController自身的一個屬性“urlMethodmappings”。
??? 2.通過一個commandName屬性,可以讓用戶自由決定綁定對象的名稱。
??? 3.簡化UrlHandlerMapping的關(guān)聯(lián)配置。對MutilActionController的bean配置進行改動時,無再需要去關(guān)心 SimpleUrlHandlerMapping的bean配置

4. 增強的MultiActionController實現(xiàn)

??? 上面提到理想MultiActionController的構(gòu)想,有三點需要實現(xiàn)。現(xiàn)在來討論實現(xiàn)它們。
??? 1. 把請求與具體方法之間的映射作為MultActionController自身的一個屬性。也就是說MultiActionController提供一個“urlMethodMapping”的屬性來保存請求路徑與對應(yīng)方法之間的映射關(guān)系。

??? 我們知道MultiActionController有一個methodNameResolver的屬性,而請求路徑與方法之間的對應(yīng)映射關(guān)系是由一個MethodNameResolver 的bean來保存的。我們一般可以配置一個PropertiesMethodNameResolver來作默認實現(xiàn)。把請求路徑與方法之間的映射關(guān)系保存在PropertiesMethodNameResolver中的“mapping”屬性中。

??? 我們可以在MultiActionController中定義一個PropertiesMethodNameResolver類型的成員變量“propertiesMethodNameResoler”。和定義一個Properties類型的成員變量“urlMethodmappings”
在MultiActionController的bean進行配置的時候把urlMethodmappings的值作為propertiesMethodNameResoler的mapping的值。然后再調(diào)用MultiActionController的setMethodNameResolver()方法,把propertiesMethodNameResoler設(shè)置為MultiActionController的methodNameResolver的屬性值。要做到這一些還應(yīng)該實現(xiàn)InitializingBean接口

public class MultiMethodController extends MultiActionController implements
InitializingBean
... {

private Properties urlMethodmappings;
public void afterPropertiesSet() throws Exception ... {

Spring架構(gòu)增強MultiActionController(上)


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論