PartV. The Web
这部分的文档,涵盖了Spring框架的表示层(尤其是web展示层)。
前几章节介绍了Spring的自己的框架结构,剩余的部分主要对讲了怎么和其他框架整合,例如Struts和JSF.
第17章 . Web的MVC框架
第18章. 视图技术
第19章. 同其他框架整合
第20章. MVC框架程序
17. Web MVC framework
17.1 Spring的Web Mvc框架的介绍
Spring的Web的模型-视图层-控制层(MVC)都是通过DispatcherServlet这个组件实现的。这个组件能够通过配置将各种请求路由给各个Controller的方法,并且提供多语言、主题设置、文件上传等功能的解决方案。
“Open for extension...”
Spring的Web框架的设计理念是:“Open for extension. Open for extension.的概念(不知道啥意思,往后看吧)”
Spring的Web框架的核心方法,很多都是final的,所以你不能用自己的方法覆写core里面的方法,这样做虽然不是强制的,但是你必须要铭记在心。
为什么这么做?详细请参考[Bob Martin, The Open-Closed Principle (PDF)]
在这个MVC框架中,你不需要事先框架的接口或者继承一些基类,而是可以直接拿过来用。他的数据绑定是非常灵活,举个例子来说,对于数据不匹配的情况,他会给出(不是抛出异常)一个验证错误,而不是提高为一个系统错误,这样,应用程序自己可以决定,怎样处理这样的错误。Thus you need not duplicate your business objects' properties as simple, untyped stringsin your form objects simply to handle invalid submissions, or to convert the Strings properly. Instead, itis often preferable to bind directly to your business objects.(不懂)
Spring的view层更加灵活。Controller的要务是从Model层拿数据,然后选择合适的视图层渲染.当然,他也可以直接写入响应的数据流来直接完成本次的请求响应。视图层的名字的辨别通过bean名称甚至是自己实现ViewResolver来完成。Model层跟视图层的通信那更加没有问题了,你可以使用Xml、Json、Atom或者其他的内容形式。数据层都能够将自身转换成合适的数据供视图层调用。
Spring的Web框架的特征:
SWF(Spring Web Flow)页面流动效果?具体参考这里吧
Spring拥有以下独一无二的特性:
- 各个职责之间的完全隔离.每个组件的职责,例如Controller、Model、View、Validator、DispatcherServlet等等都是相对独立的
- 通过JavaBean可以直接的配置框架或者是应用程序的类。
- @PathVariable, @RequestParam, @RequestHeader,通过这样的申明来定义controller或者是参数。
- 可以重用的业务代码,而不是需要从core类里面来继承或实现他的接口,想用就用。
- 自定义的个性化的数据绑定和验证。
- 不管你的视图层用的什么技术,Model的Map都能够很简单和方便的支持
- 一个JSP的表单标签库让你JSP写起来,更加容易.
- 其他的需要你慢慢体会
可插拔的MVC组件
如果你想用自己的MVC实现,因为你已经积累了太多的经验或者是其他什么原因,也没问题的,Spring支持不带MVC的功能。
17.2 The DispatcherServlet
Spring的这个Servlet是一个核心Servlet,和其他的MVC框架一样,他是一个请求驱动的,负责把请求分发到正确的Controller中去处理。并且还提供了很多方法以促进应用的开发。他充分的实现了Spring的loC原则,因此可以让你用Spring的所有的特性。他在应用中所处的位置如图一所示:
图一:MVC的请求处理流程
DispatcherServlet是一个实实在在存在的Servle集成于HttpServlet,并且被定义在你的网站的Web.xml中。你需要配置你的网站的映射到这个Servlet上,这是一个标准的JavaEE 的Servlet配置,下面一段代码是一个示例。
当然,你也可以通过程序来设置,下面这段代码跟上面的配置文件,实现的效果一样。
WebApplicationInitializer是由Spring的MVC提供的一个接口,用来让你基于代码的配置,并且能够自动的初始化Servlet的容器。AbstractDispatcherServletInitializer实现了这个接口,非常容易的注册了DispatcherServlet通过映射关系。
以上只是配置的第一步,接下来,你需要通过上面初始化的DispatcherServlet来配置各种Beans。你可以在5.4章节中查看此详细内容。每一个DispatcherServlet都拥有一个自己的WebApplicationContext,承担了在WebApplicationContext中定义的所有的Beans,他们的关系如下图二所示:
这些Beans被定义在WEB-INF的下面的[servlet-name]-servlet.xml文件中,并且会覆盖掉全局的beans配置。让我们看看下面的web.xml的配置:
然后你必须在WEB_INF下面,/WEB-INF/golfingservlet.xml这个文件中,配置所有的需要的组件(Beans) WebApplicationContext 是ApplicationContext的一个子类,并且包含了额外的web开发需要的特征。
extra features necessary for web applications. 他的特别之处在于可以定义样式的主题(see Section 17.9, “Using themes”), 他能够知道跟哪个Servlet关联 (by having a link to the ServletContext). WebApplicationContext在ServletContext中是受限制的, 通过 RequestContextUtils中的静态方法你能够在你需要的时候访问 WebApplicationContext .
Special Bean Types In the WebApplicationContext
Spring的 DispatcherServlet使用特殊的 beans 去处理请求并且渲染合适的模板。这些 beans 都是Spring MVC的一部分. 你可以通过配置WebApplicationContext来决定使用哪个. 然而,你也可以不用配置,因为Spring会提供一大票的默认的beans供你使用。下一章节会介绍更多,我们可以先看看下面这些表里的beans。
Table 17.1. WebApplicationContext的特殊的beans
Bean type | 解释 |
HandlerMapping | 将进来的请求映射到相应的模块去处理,通过注解。也就是说,注解到controller的映射是在这里实现的。 |
HandlerAdapter | 让DispatcherServlet能够调用Handle,不管当前是否已经调用.例如,有时候你处理一个请求,需要调用其他的Handle,这个时候,他就将DispatcherServlet从这些细节里解放了出去 |
HandlerExceptionResolver | Handle的异常处理的 |
ViewResolver | 解析模板的 |
LocaleResolver | 解析多语言的 |
ThemeResolver | 解析多主题的 |
MultipartResolver | 多任务处理的,例如上传文件 |
FlashMapManager | 常用来进行redirect |
DispatcherServlet的默认配置
上述的beans的默认使用详细信息在DispatcherServlet.properties in the package org.springframework.web.servlet.中。每一个beans都有自己合理的默认设置,未来的章节将会介绍如何设置和定制符合自己的配置。
抛开细节,你最最需要理解的是一旦你配置了一个自己的beans,例如InternalResourceViewResolver in your WebApplicationContext,你自己的beans将会被用于系统中。例如你定义了一个InternalResourceViewResolver,然后默认的实现ViewResolver就自动被忽略了。In Section 17.15, “Configuring Spring MVC”你将会学到如何配置自己的Spring的MVC,因此这章节是非常重要的,会帮助你理解将来的内容。
DispatcherServlet 处理流程
假设你设置好了DispatcherServlet,然后现在来了一个请求,那么过程将如下:
- 寻找WebApplicationContext并作为一个属性,在当前controller中和其他组件中使用,相关联的限制在DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE.中定义
- The locale resolver多语言的组件启动,如果你没有开启这种功能,此步将被跳过
- The theme resolver启动,将会处理主题相关的设置,如果没设置,跳过此步
- 上传文件等,需要多文件处理,则multipart file resolver启动
- 一个合适的handler将被启动
- 如果一个model 被返回, 那么视图层将被渲染
在请求的过程中如果有异常发生,那么Handler exception resolvers 组件将发挥作用
17.3 Controllers层的实现
Controoler通过服务接口,能够让你操控应用程序的行为。Spring的Controller能够转换用户的输入,并抛入Model层,最后再view层输出。由于是使用的抽象的实现,所以,你可以在这里大胆的发挥。
Spring2.5的Controller的配置采用注解的风格,例如@RequestMapping, @RequestParam, @ModelAttribute等等。这种方式不仅支持Servlet MVC还支持Portlet MVC。通过这种方式,用户不需要基类以及接口。
在Spring的很多示例程序中,大量应用了这种注解的方式,例如:
例如上面这段程序,增加了一个Model,然后以字符串的方式,返回了视图层的模板名称,现在看不懂还不要紧,这一章节将详细的介绍这些内容,包含有哪些注解,以及他们怎么用。
通过@Controller定义Controller
Spring不需要你