1.Controller的集成层次体系
次体系
2.MultiActionController:
可以身兼数值,对于一组逻辑上相近的web请求,例如针对同一对象的CRUD操作,或者针对同一对象的一个或者一组查询操作,我们可以统一的将这些请求交割MultiActionController来处理,而不必为每一个请求单独实现一个集成AbsractController的处理类。MultiActionController类似于Struts中的DispacherAction。
2.1 Web请求的处理方法要求
Web请求的处理方法必须符合一定的要求,如下所示:
(ModelAndView|Map|void)methodName(HttpServletRequest request,HttpServletResponseresponse[,(HttpSession session|Object command)]);
2.2 MultiActionController的代理对象
MultiActionController使用代理对象的好处在于,委派对象不需要世界任何接口或继承任何父类,干净利落。
<bean name=”/groupAdmin.do”class=” org.springframework.web.servlet.mvc.multiaction.MultiActionController”>
<property name = “delegate”ref=”deleController”/>
<property name =”methodNameResolver”ref=” methodNameResolver”/>
</bean>
2.3.MethodNameResolver
MultiActionController的助手,MethodNameResolver的作用就是帮助Controller判断使用哪个方法处理当前的Web请求,它有三个子类:
2.31 InternalePathMethodNameResolver
默认的MethodNameResolver,如果没有指定MethodNameResolver,则默认采用此种方式。它将提取URL的最后一个(/)之后的部分并去除扩展名。作为要返回的方法名称。Eg: /example/loginController/login.do 会调用login方法。
<bean id="internalPathMethodNameResolver"
class="org.springframework.Web.servlet.mvc.
multiaction.InternalPathMethodNameResolver">
<property name="prefix" value="rate_"/>
</bean>
2.32 PropertiesMethodNameResolver
可以指定完全匹配的映射关系。或者适应ant形式的路径匹配模式所表达的映射关系。
<bean id = “propsMethodNameResoler”
class=”org.springframework.web.servlet.mvc.multiaction.PropertiesMethodNameResolver”>
<property name=”mappings”>
<value>
/list.do=list
/update.do=update
</value>
</property>
</bean>
2.33 ParameterMethodNameResolver
允许根据请求中的某个参数值作为映射的方法名。也允许使用请求中的一组参数来映射处理方法名称。下面是两种方式的介绍,需要强调的是如果mehodParamNames和paramName两个属性都设置了的话,两种策略同事使用,并且mehodParamNames属性代表的映射策略优先考虑。
a. 根据请求中的某个参数值作为映射的方法名
http://host:post/WebPro/example/logController.do?action=login,则Controller的login方法会被调用
<bean class=”org.springframework.web.servlet.mvc.multiaction.ParameterMethodNameResolver”>
<property name = “paramName” value=”action”
</bean>
b. 使用请求中的一组参数来映射处理方法名称
<bean class=”org.springframework.web.servlet.mvc.multiaction.ParameterMethodNameResolver”>
<property name = “methodParamNames” value=”list,update,delete”>
<property name = “defaultMethodName” value=”list”>
</bean>
3.SimpleFormController:
继承自BaseCommandController,提供了数据绑定和数据验证功能。
3.1 数据绑定
对于BaseCommandController及其子类,可以通过设置commandClass属性来设置数据绑定的目标Command的对象类型。
<bean name=”simpleFormController” class=” org.springframework.web.portlet.mvc.SimpleFormController”>
<property name = “commandClass”ref=” commandClass”/>
</bean>
数据绑定的过程:
(1) 当web请求到达之后,SpringMVC框架类将提取当前Web请求中的所有参数名称,然后遍历它,以获取对应每个参数的值,获取的参数名与参数值通常放入一个值对象(PropertyValue)中,最终我们将拥有所有需要绑定的参数和参数值的一个集合。
(2) 有了即将绑定到目标Command对象的数据来源之后,我们即可将这些数据根据Command对象中各个域属性定义的类型进行数据转型,然后设置到Command对象上。而参数值与Command对象类型转换工作有PropertyEditor负责。可以自定义添加PropertyEditor。支持BeanWrapperImpl中的默认的PropertyEditor所不支持的类型。
3.2 数据验证
Spring数据验证的支持是不仅局限于SpringMVC中使用的。其核心类为org.springframework.validation.Validator和org.springframework.validation.Errors
Validator.java定义如下:
publicinterface Validator {
boolean supports(Class<?> clazz);
void validate(Object target, Errorserrors);
}
Validator使用方式:
(1) 验证对象本身
(2) 验证对象的相应属性
3.3 SimpleFormController处理流程
整个表单处理流程将以isFormSubmission(request)的判定结果为基准。划分为“表单显示阶段”(结果为true)和“处理表单提交阶段(结果为false)”
(1) 表单显示阶段
a. 创建或者获取表单对应的Backing Object,Backing Object实际上对应的是Command的对象,由formBackingObject(PortletRequest request)提供,如需特殊实现,可覆盖此方法,例如:需要展示的不是Command对象,而是数据库中更新过的数据,需要重写formBackingObject(PortletRequest request)方法,查询数据库,返回最新结果,
b. 初始化binder
c. 执行数据绑定, 只有Controller的bindOnNewForm属性设置为true,才会执行数据绑定。通常在显示表单之前不会进行数据绑定。bindOnNewForm默认为false
d. referenceData方法:SimpleFormControll会将referenceData返回的模型数据添加到ModelAndView中,可以使用此方法初始化一些表单中需要的模型数据。
(2) 处理表单提交
a. 获取要绑定的目标对象:根据SimpleFormControll的sessionForm属性是否为true,如果为true则将从HttpSession中获取已经存入的Command的对象,否则将调用formBackingObject(PortletRequestrequest)方法重新生成一个Command对象
b. 初始化DataBinder
c. 执行数据绑定和数据校验
d. 处理表单提交:提交前判断数据校验的结果,如果存在校验错误,则重新显示表单界面,并显示错误信息。如果通过验证,则判断请求是否是一个FormChangeRequest,通过isFormChangeRequest(request)进行判断,默认返回false,可以覆写该方法。如果返回true,则不需要处理提交操作,而是将视图图重新导向原页面。可以通过覆写onFormChange方法增加自定义逻辑,比如更改Command对象状态。以上的检查都通过后则会进行提交操作。doSubmitAction(Object command)会被调用,可以覆写改方法或者它的上级方法onSubmitAction(Object command)来进一步处理提交请求,调用相应的业务逻辑。
Demo:
public class LoginControllerextends SimpleFormController {
public LoginController() {
setCommandClass(“User.class”);
setCommandName(“user”);
}
protected void doSubmintAction(Object command) throwsException {
}
}
4 AbstractWizardFormController
用于提供向导式的多页面实现流程。4.1AbstractWizardFormController 的特定参数
AbstractWizardFormController使用特定参数来决定如何对当前请求进行处理,特定的参数可以分为三类:
A. PARAM_TARGET参数。PARAM_TARGET参数用于指定目标界面,它的形式为_target后缀页面索引,比如_target0,_target1等。当AbstractWizardFormController实现类接收到这种类型的参数的时候,它只是将当前请求中的相应参数绑定到Command对象上,然后根据PARAM_TARGET参数后缀的目标页面索引显示相应的页面。
B. PARAM_FINISH参数。PARAM_FINISH参数的表示形式_finish。如果AbstractWizardFormController接收到该参数,则表示真个向导流程结束,可以调用processFinish(..)方法处理最终的表单数据,并将页面转向任何一个想要转到的页面。
C. PARAM_CANCEL参数。PARAM_CANCEL参数的表示形式为_cancel。当接收到该参数的时候,表示用户要取消当前的向导流程。默认情况下,AbstractWizardFormController不支持该参数处理,但我们可以通过覆写processCancel(..)方法来改变这种默认行为。唯一要做的,可能只是返回一个ModelAndView实例,其中只包含了一个逻辑视图名。
Eg:
Jsp:
<input type=”submit”name=”_target0” value=”上一步”>
<input type=”submit”name=”_target2” value=”下一步”>
<input type=”submit”name=”_cancel” value=”取消”>
<input type=”submit”name=”_finish” value=”结束问卷”>
Xml:
<bean name=”survey.do”class=” com.cn.surveyWizardFormAction”>
<property name = “successView” value=”surveyResult”>
<property name = “page” value=”welcome,carManuFacturers,carPriceScope”>
</bean>
5. AbstractCommandController
继承了BaseCommandController的数据绑定以及数据验证功能支持。自身也定义了简单的请求处理流程,但是它的主要目的不是面向表单的处理。实际上,它只是一个加强型的AbstractController。直接继承AbstractController与直接继承AbstractCommoandControllre差不多,唯一的区别就是,后者进一步规范了参数的获取和验证操作。
6. ParameterizableViewController
ParameterizableViewController没有任何处理逻辑,只是返回一个包含逻辑视图名的ModelAndView实例。让我们依然可以依赖于ViewResolver的映射能力向客户端屏蔽不同视图的差异性。
Eg:
<bean name=”survey.do”class=” org.springframework.web.portlet.mvc.ParameterizableViewController”>
<property name = “viewName” value=”jsp/view”>
</bean>
7. UrlFilenameViewController
ParameterizableViewController一次只能映射一个视图文件。如果有一组视图文件都需要不做任何处理直接返回的话,我们就需要使用UrlFilenameViewController,而不必为每个页面配置一个Controller。
Eg:会跳转到视图名为help/test的视图
Xml:
<bean name=”/help/*”class=” org.springframework.web.servlet.mvc.UrlFilenameViewController”>
<property name = “prefix” value=”help/”>
</bean>
Jsp:
<a href=”<c:urlvalue=’help/test.do’>”>Go Help!</a>