在使用Spring提供的控制器时,AbstractController和SimpleFormController是应用得最多的。 AbstractController是最基本的Controller,可以给予用户最大的灵活性。SimpleFormController则用于典型 的表单编辑和提交。在一个需要增,删,改,查的需求中,增加和修改扩展SimpleFormController完成,删除和查询则扩展 AbstractController完成。
但是像上面那样完成某一业务对象的增,删,改,查,都属于一类相关的业务。把一类相关的操作分布到不同的类去完成,违返“高内聚”的设计原则。这样四个业务操作需要四个类来完成,造成太多的类文件,难以维护和配置。
所以Spring借鉴Struts的DispatchAction提供了类似功能的MultiActionController。可以实现不同的请求路径 对应MultiActionController中的不同方法,这样就可以把相关的操作都在一个类的相关方法中完成。这样使得这个类具有“高内聚”,也利 于系统的维护,还避免了重复代码。增加和修改操作的数据验证逻辑是很相似的,使用MultiActionController后就可以让增加和修改操作共用一段数据验证逻辑代码。
1. 使用MultiActionController
MultiActionController会使不同的请求映射为不同方法,这里是一个实现用户信息增删改查的例子:
1.1 SampleMultiMethodController实现
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 " ; // 提交成功后显示的view
private static final String userInfoListKey = " userInfoList " ; // 用户信息列表key值
private final String userIdParam = " id " ; // userid
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配置
< 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的缺点
数 据绑定支持不好。SimpleFormController专门用来支持编辑和表单提效的,它支持数据绑定,在这方面做得很好。可以把jsp页面的字段值 绑定为某一对象(Command)。可以自定义command的名称。虽然MultiActionController也支持数据绑定,但是它并不支持自 定义command的名称。它默认的comamnd名称为”command”。这也是不便于维护的,对象应该有一个代表自身含义的名字。如果所有页面的绑 定对象都以”command”作为名字,那将难以理解。MultiActionController支持数据绑定的方法参见上面例子的saveUser方 法。
3. 增强的MultiActionController实现