18. Web MVC 框架

18.1 Spring Web MVC 框架的介绍

Spring Web模型视图控制器(MVC)框架是围绕一个DispatcherServlet设计的,它将请求分派给处理程序,具有可配置的处理程序映射,视图解析,区域设置,本地化和主题解析,并且支持上传文件。默认的处理是基于注解@Controller@RequestMapping,提供一系列灵活的处理方法。随着Spring 3.0的推出,通过@PathVariable或者其他注解,@Controller机制开始允许你去创建 Rest风格的web站点和应用。

在Spring Web MVC 和 Spring中一条关键的准则是“对扩展开放,对修改关闭”

在Spring Web MVC中一些核心类的方法被标注为final,由于开发者不能用自已的方法去覆盖这些方法,这并不是任意的,而是特别考虑到这个原则。

对于这个准则的解释,请参考Seth Ladd的Expert Spring Web MVC和Web Flow; 具体参见第一版第117页的“A Look At Design”一节。 或者参见

Bob Martin, The Open-Closed Principle (PDF)

当你使用Spring MVC时,你不能在final方法增加切面。例如,你不能在AbstractController.setSynchronizeOnSession()增加切面,有关AOP 代理的更多信息以及为什么不能再Final方法增加切面,查看第7.6.1节“了解AOP代理”

在Spring Web MVC中,您可以使用任何对象作为命令或表单支持对象;你不需要实现一个特别架构接口或者基类。Spring数据绑定非常灵活:例如,你可以使用程序将类型不匹配当作验证错误而不是系统错误。 因此,您不需要将您的业务对象的属性复制为简单的无格式的字符串,仅用于处理无效提交,或者正确转换字符串。 相反,通常最好直接绑定到您的业务对象。

Spring 的视图处理也是相当灵活,控制器通常负责准备具有数据和选择视图名称的模型映射,但它也可以直接写入响应流并完成请求。视图名称解析可通过文件扩展或Accept标头内容类型协商进行高度配置,通过bean名称,属性文件或甚至自定义的ViewResolver实现。模型(MVC中的M)是一个Map接口,可以完全提取视图技术,你可以直接与基于模板的渲染技术(如JSP和FreeMarker)集成,或直接生成XML,JSON,Atom和许多其他类型的内容。 模型Map可以简单地转换成适当的格式,如JSP请求属性或FreeMarker模板模型。

18.1.1 Spring Web MVC的特点

Spring Web 流程

Spring Web 流程 (SWF)的目的是成为最好的Web页面应用流程管理方案,SWF与Servlet 和Portlet 环境中的Spring MVC和JSF等现有框架集成。如果你有一个这样的业务流程,使用会话模型比纯粹的请求要优,那么SWF可能是一个选择。

SWF允许您将逻辑页面流作为在不同情况下可重用的自包含模块捕获,因此非常适合构建引导用户通过驱动业务流程的受控导航的Web应用程序模块。

更多关于SWF的信息,请点击Spring Web Flow website.

Spring 的Web模块包含许多独特的web支持特性:

  • 明确并分离的角色.每个角色-控制器,验证器,命令对象,构建对象,模型对象,分发器,映射处理器,视图解析等等都是完全的一个特定对象
  • 框架和应用程序类作为JavaBeans的强大而直接的配置。 此配置功能包括跨上下文的简单引用,例如从Web控制器到业务对象和验证器。
  • 可适配,无入侵,灵活,定义您需要的任何控制器方法签名,可能使用给定方案的参数注释之一(例如@RequestParam,@RequestHeader,@PathVariable等)。
  • 可重用的业务代码,不需要重复,使用现有的业务对象作为命令或表单对象,而不是仿照它们来扩展特定的框架基类。
  • 自定义绑定和验证,类型不匹配作为应用程序级验证错误,保持违规值,本地化日期和数字绑定等,而不是只使用仅包含字符串的表单对象进行手动解析和转换为业务对象。
  • 自定义的处理程序映射和视图解析,从简单的URL配置策略到复杂的,特制的策略,Spring比Web MVC框架更灵活,这些框架需要特定的技术。
  • 灵活的模型转换,具有名称/值的模型传输Map支持与任何视图技术的轻松集成。
  • 本地,时区,主题自定义,支持具有或不具有Spring标签库的JSP,支持JSTL,支持FreeMarker而不需要额外的网桥等等。
  • 一个简单而强大的JSP标签库,被称为Spring标签库,为数据绑定和主题等功能提供支持。 自定义标签允许在标记代码方面具有最大的灵活性。 有关标签库描述符的信息,请参见附录 Chapter 40,spring JSP Tag Library
  • 在Spring 2.0中引入的JSP表单标签库,使得在JSP页面中的写入表单更容易。 有关标签库描述符的信息,请参见附录 Chapter 41,spring-form JSP Tag Library
  • Bean的生命周期范围限定在当前的HTTP请求或HTTP Session中。 这不是Spring MVC本身的一个特定功能,而是Spring MVC使用的WebApplicationContext容器。 这些bean范围在 Section 3.5.4, “Request, session, application, and WebSocket scopes”

18.1.2 其他MVC实现的可插拔性

对于某些项目,非Spring MVC实现更为可取。许多团队希望利用他们现有的技能和工具投资,例如使用JSF。

如果您不想使用Spring的Web MVC,但打算利用Spring提供的其他解决方案,您可以轻松地将您选择的Web MVC框架与Spring集成。通过其ContextLoaderListener简单地启动一个Spring根应用程序上下文,并通过任何动作对象中的ServletContext属性(或Spring的各自的帮助方法)访问它。没有涉及“插件”,因此不需要专门的集成。从Web层的角度来看,您只需使用Spring作为库,将根应用程序上下文实例作为入口点。

即使没有Spring的Web MVC,您的注册bean和Spring的服务也可以在您的指尖。在这种情况下,Spring不会与其他Web框架竞争。它简单地解决了纯Web MVC框架从bean配置到数据访问和事务处理的许多方面。所以您可以使用Spring中间层和/或数据访问层来丰富您的应用程序,即使您只想使用JDBC或Hibernate的事务抽象。