spring mvc
|-org.springframework.context.support.ApplicationObjectSupport
|-org.springframework.web.context.support.WebApplicationObjectSupport
|-org.springframework.web.servlet.support.WebContentGenerator
|-org.springframework.web.servlet.mvc.AbstractController
|-org.springframework.web.servlet.mvc.BaseCommandController
|-org.springframework.web.servlet.mvc.AbstractFormController
|-org.springframework.web.servlet.mvc.SimpleFormController
1.ApplicationObjectSupport implement ApplicationContextAware 它是应用对象的一个方便的父类,对application context感知,例如查找协作的beans 或是 context中描述的资源。 它保持对application context的引用,并提供一个初始化回调的方法。 而且,它提供大量方便的方法用于查找资源。
2.WebApplicationObjectSupport 它是应用对象的一个方便的父类,运行在WebApplicationContext里。提供了getWebApplicationContext, getServletContext,和getTempDir methods.
3.WebContentGenerator 它对于任何类型的web内容发生者而言是一个方便的父类,例如AbstractController和WebContentInterceptor. 对于那些拥有自己HandlerAdapter的个性化的handlers,也是有用的。支持HTTP cache控制的选项。通过userExpiresHeader和userCacheControllHeader两个属性可以确定 HTTP headers。
4.AbsractController implements Controller 是控制类的父类,运用了模板模式(Template Method)的设计模式正如在Controller接口声明的,许多功能在抽象的控制类中已经提供。它是最重要的基础控制类之一,提供了许多基础的服务,例如产生 caching headers ,以及可以使对所支持的方法(get/post)有效或无效。工作流程: a.handleRequest() 被DispatcherServlet 调用; b.检测所支持的请求方法,若不支持抛ServletException; c.如果使要求事务的,就从session中取,若取不到抛ServletException; d.如果需要,可以根据配置的cacheSeconds属性来设置caching headers; e.调用抽象的方法handleRequestInternal(), 这个由子类来实现功能,返回ModelAndView对象。 对外暴露的属性,可以配置 name default description supportedMethods GET,POST 用逗号分隔这个控制类支持的请求方法,例如GET, POST and PUT requireSession false 表明被控制类处理的request是否需要事务,它保证控制类可以通过request.getSession()获取事务, 不必担心空指针,若得不到事务,抛ServletException cacheSeconds -1 表明包含在request之后的response的cache header的秒数。0表示没有cache,-1表示不生成各种 header,正数表示生成header,秒数表示cache内容的时间
5.BaseCommandController 它实现了:接收请求后创建对象(command object),并试图根据请求的参数组装对象 它是一切试图实现下面功能的控制类的基础:根据请求参数组装JavaBeans,校验javabeans的内容,使用custom editors(实现PropertyEditors)的在对象和字符串之间进行转换. 提出了三个概念: Command Class: 每个请求产生一个command class的实例,并根据请求参数组装对象。一个command class可以是基础的java类;唯一的要求有无参数的构造函数。 command class最好是一个java类,以便可以通过请求参数来组装对象属性。 Populating using request parameters and PropertyEditors: 一但接收一个请求,任何BaseCommandController将试图根据请求参数来填充command对象。这种做法用的是典型的、众所周知的javaBeans属性的概念。当一个名字为"firstName"请求参数存在,框架将试图去调用setFirstName([value])传递参数的值。嵌套属性也是支持的。例如一个参数名字为"address.city" 在command类面将会调用getAddress().setCity([value])。 重要的一点:你不能限制javabeans中都是string参数。通过PropertyEditor的概念(在java.beans里),你可以将字符转成对象,或者用其他的方式。例如,对于一个名字为"locale"的请求参数值为"en",只要你在控制类注册了正确的PropertyEditor,setLocale(Locale loc)是一个不错的选择。 Validators: 在控制类成功的根据参数组长commnd对象后,它可以用配置的validators类来验证对象.校验的结果放置在Errors对象里,以供View去返回任何输入的问题。 工作流程:(和父类一样) 暴露的属性(除了父类的之外) name default description commandName command 绑定初始化command对象的名字 commandClass null 接收请求后,被用请求参数填充的类。什么对象被使用,对象是否被创建?这是由它的子类和子类的的配置和方法来决定的。 validator null 校验类属性。校验类将在子类的工作流程适当的地方被调用来校验command对象。 validateOnBinding true 表示在command对象被参数组装后,是否需要校验command对象。
6.AbstractFormController Form controller是可以根据请求自动组装一个form bean的控制类。可以每个请求产生一个新的bean,也可以设置sessionForm属性为true后使用同一个bean. 这个类是架构的基础子类,例如SimpleFormController和AbstractWizardFormController,和你自己提供的控制类的父类。 form-input views 和after-submission view由程序来提供。使用SimpleFormController,可以通过配置文件来提供这些views 子类必须覆写showForm来准备form view,覆写processFormSubmission来处理提交的请求。对于后者,诸如类型不匹配等绑定错误将通过提供的"errors"来报告。对于附加的个性化的form校验,validator可以被使用,通过同样的”errors“来报告。 用Spring提供的AbstractFormController和Structs的Action概念对比,你可以使用普通的javabeans或者依赖于数据库的javabeans,而不用实现类似于Structs的ActionForm这样的架构描述类。通过一个java.beans.PropertyEditor的概念,许多复杂的属性(日期,场景,或者你应用里面复杂的类型)被提交到控制类。 工作流程: a.控制类接收一个新form请求,通常是get方式的。 b.缺省调用formBackingObject(),返回一个配置的CommandClass的实例. 也可以覆写此方法,例如从数据库获取对象。 c.调用initBinder(),这允许你为command类特别的属性注册custom editors(通常是非原始类或String类型的) 这将为属性值而调整字符串。例如,本地化的日志字符串 d.只有当bindOnNewForm被设置为true,ServletRequestDataBinder将被用根据请求参数做组装一个新的form对象 e.调用showForm()返回一个将被调整view,这个方法子类必须实现 f.showForm()的实现中调用referenceData(),你可以现实此方法用于当编辑form时提供一些相关的引用数据。(例如,本地化对象,你需要用户选择一个) g.暴露Model,递交view后,用户可以填充form h.AbStractFormController接收到一个form提交,通常时post方式的。可以通过覆写isFormSubmission()方法,来使用不同的检测form提交的方法。 i.如果sessionForm 没有设置为true,formBackingObject()被调用来获取一个新的form对象;否则,控制类试图查找绑定到session的command对象。 如果没有找到,将调用handleInvalidSubmit(),这个方法缺省是创建一个form对象,并重新提交。 j.调用ServletRequestDataBinder,用请求的参数来组装当前的form对象。 k.调用onBind(HttpServletRequest,Object,Errors),这个方法允许你在校验之前在绑定之后做一个个性化的处理。(例如可以手动将请求参数绑定到对象的属性,让校验类可见) l.如果validateOnBinding被设置,注册的Validator类被调用.Validator将校验form对象的属性,通过"Errors"对象登记相应的错误。 m.调用onBindAndValidate(),这个方法允许你做个性化的绑定和校验(例如手动的绑定请求参数,通过外部的Validator校验它们)。 n.调用processFormSubmission()处理提交信息,无论有还是没有errors.这个方法将被子类实现。 在session form 模式下,在一个session里一个提交没有一个已经存在的form对象,被认为是不合理的,就想在浏览器里面重复提交,重复刷新。这时handleInvalidSubmit方法被调用,这个方法缺省是处理重复提交的.它可以在子类被覆写,提供相应的消息或重定向到新的form,从而避免了重复提交。在这种情况下,session中的form对象可以被认为是一个事务的token. 视图views将不能从session中获取beans,但是可以从请求中获取form controller预备的。记住一些视图技术例如Velocity不能访问一个HTTP session 暴露的属性 (由子类定义): name default description bindOnNewForm false 表示在创建一个新的form时是否需要绑定servlet的请求参数。否则,参数只在提交的是否绑定。 sessionForm false 表示当一个用户请求一个新的form时,是否将form对象保存在session中。这允许你从数据库获取 form对象,编辑它,再把它做持久化。否则新的command对象在每次请求都产生一个新的。
7.SimpleFormController 具体的FormController实现,提供可配置的form和success views,和一个onSubmit链,易于覆写。在校验出现错误时,自动重新提交到form view,在校验合法的情况下自动提交successview. 工作流程和AbstractFormController没有什么太大的区别。唯一不同的是你不用实现 showForm和processFormSubmission: 一个form view 和一个success view 可以被配置。 工作流程(对父类而言,新增部分): a.调用processFormSubmission,如果在绑定和校验是出现错误,检测Errors对象。 b.如果错误出现,控制类将返回配置的form view,又一次显示form(或者根据错误信息递交) c.如果isFormChangeRequest被覆写,对于请求返回true,控制类将返回formview。在这种情况下 控制类将禁用校验。目的是,在一些情况下改变form的结构而不会引起校验。 d.如果没有错误发生,控制类将调用使用全部参数的onSubmit方法,这个方法在缺省的情况下的实现是代理到使用command对象的onSubmit方法。后者的缺省实现将返回配置的success view。考虑实现 doSubmitAction(java.lang.Object),doSubmitAction针对简单的执行一个提交并返回success view。 通过覆写onSubmit()方法可以使提交行为更个性化.如果需要的话,提交动作也可以执行个性化的校验,出现校验错误时调用showForm重新展示form view. 暴露的参数(其他在父类定义) name default description formView null 表示在提交时出现校验错误,哪个view将被展示 successView null 表示在成功提交后什么view将展示.例如这个success view可以展示一个提交总结.常用的方法时覆写其中一个onSubmit()方法