原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。 http://tonyaction.blog.51cto.com/227462/84893
第一章
Spring
的
MVC
框架
6.1 Spring MVC
概要
Spring
的web框架是围绕DispatcherServlet
来进行设计的。DispatcherServlet
的作用是将请求分发到不同的处理器。Spring的web框架包括可配置的处理器(handler)映射、视图(view)解析、本地化(local)解析、主题(theme)解析以及对上传文件解析。处理器是对Controller
接口的实现,该接口仅仅定义了ModelAndView handleRequest(request, response)
方法。你可以通过实现这个接口来生成自己的控制器(也可以称之为处理器),但是从Spring提供的一系列控制器继承会更省事,比如AbstractController
、AbstractCommandController
和SimpleFormController
。注意,你需要选择正确的基类:如果你没有表单,你就不需要一个FormController。这是和Structs的一个主要区别。Spring的视图解析相当灵活。一个控制器甚至可以直接向response输出一个视图(此时控制器返回ModelAndView的值必须是null)。在一般的情况下,一个ModelAndView实例包含一个视图名字和一个类型为Map的model,一个model是一些以bean的名字为key,以bean对象(可以是命令或form,也可以是其他的JavaBean)为value的名值对。对视图名称的解析处理也是高度可配置的,可以通过bean的名字、属性文件或者自定义的ViewResolver实现来进行解析。实际上基于Map的model(也就是MVC中的M))是高度抽象的,适用于各种表现层技术。也就是说,任何表现层都可以直接和Spring集成,无论是JSP、Velocity还是其它表现层技术。Map model可以被转换成合适的格式,比如JSP request attribute或者Velocity template model。
Spring Web MVC
框架提供了大量独特的功能,包括:
1)
清晰的角色划分:
控制器(
controller
)、验证器(
validator
)、命令对象(
command object
)、表单对象(
form object
)、模型对象(
model object
)、
Servlet
分发器(
DispatcherServlet
)、处理器映射(
handler mapping
)、视图解析器(
view resolver
)等等。
每一个角色都可以由一个专门的对象来实现。
2)
强大而直接的配置方式:
将框架类和应用类都作为
JavaBean
配置,支持在一个
context
中引用其他
context
的中
JavaBean
,例如,在
web
控制器中对业务对象和验证器(
validator
)的引用。
3)
可适配、非侵入的controller
:
你可以根据不同的应用场景,选择合适的控制器子类(
simple
型、
command
型、
form
型、
wizard
型、
multi-action
型或者自定义),而不是从单一控制器(比如
Action/ActionForm
)继承。
4)
可重用的业务代码:
你可以使用现有的业务对象作为命令或表单对象,而不需要在类似
ActionForm
的子类中重复它们的定义。
5)
可定制的绑定(binding
)
和验证(validation
):
比如将类型不匹配作为应用级的验证错误,这可以保存错误的值。再比如本地化的日期和数字绑定等等。在其他某些框架中,你只能使用字符串表单对象,需要手动解析它并转换到业务对象。
6)
可定制的handler mapping
和view resolution
:
Spring
提供从最简单的的
URL
映射,到复杂的、专用的定制策略。与某些
MVC
框架强制开发人员使用单一特定技术相比,
Spring
显得更加灵活。灵活。
7)
灵活的model
转换:
在
Springweb
框架中,使用基于
Map
的名
/
值对来达到轻易地与各种视图技术的集成。
8)
可定制的本地化和主题(theme
)解析:
支持在
JSP
中可选择地使用
Spring
标签库、支持
JSTL
、支持
Velocity
(不需要额外的中间层)等等。
9)Spring Bean
的生命周期可以被限制在当前的HTTP Request
或者HTTP Session
。
准确的说,这并非
Spring MVC
框架本身特性,而应归属于
Sping MVC
使用的
WebApplicationContext
容器。
6.2
将请求映射到控制器
和其它
web
框架一样,
Spring
的
web
框架是一个请求驱动的
web
框架,其设计围绕一个中心的
servlet
进行,它能将请求分发给控制器,并提供其它功能帮助
web
应用开发。然而,
Spring
的
DispatcherServlet
所做的不仅仅是这些,它和
Spring
的
IoC
容器完全集成在一起,从而允许你使用
Spring
的其它功能。
代码清单
1
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-config-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
代码清单
1
中我们定义了
DispatcherServlet
取名
dispatcher
并且将所有以
.do
结尾的请求都交由
dispatcher
处理
,
并且为他指定了名为
spring-config-mvc.xml
的
Spring
配置文件。如果我们没有指定配置文件的名称
Spring
会在
web
应用的
WEB-INF
文件夹下寻找名为
[servlet-name]-servlet.xml
的配置文件如
dispatcher
-servlet.xml
代码清单
2
<bean id="viewResolver" class="org.springframework.web.servlet.view.
InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
<bean id="simpleUrlHandlerMapping" class="org.springframework.web.servlet.handler.
SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/helloworld.do"> helloworldController</prop>
</props>
</property>
</bean>
<bean id=" helloworldController "
class="
com.tony.web.controller
.
HelloworldController
"/>
import
javax.servlet.http.HttpServletRequest;
import
javax.servlet.http.HttpServletResponse;
import
org.springframework.web.servlet.ModelAndView;
import
org.springframework.web.servlet.mvc.Controller;
public
class
HelloworldController
implements
Controller {
@Override
public
ModelAndView handleRequest(HttpServletRequest request,
HttpServletResponse response)
throws
Exception {
//
向
HttpServletRequest
中加入一个名为
message
值为
HelloWorld
的对象
request.setAttribute(
"message"
,
"HelloWorld"
);
//
返回一个
ModelAndView
对象通过
viewResolver
的处理
//
页面跳转至
/WEB-INF/jsp/
helloworld.jsp
return
new
ModelAndView(
"helloworld"
);
}
}
代码清单
1
中
配置 InternalResourceViewResolver,它是 jsp 渲染模板的处理器。如果你告诉 InternalResourceViewResolver 处理一个名为
helloworld
的模板时,它会渲染 /WEB-INF/jsp/
helloworld
.jsp
文件。把 jsp 文件放到 /WEB-INF/jsp/ 目录下是被鼓励的,这样可以防止用户不经过 Controller 直接访问 jsp 文件从而出错。
配置
SimpleUrlHandlerMapping
,
在上面的配置文件中,
/
helloworld
.do
的请求将被
helloworldController
处理。
"/
helloworld
.do"
和
"
helloworldController
"
是变量,你可以更改。但是你注意到了吗,
hello.do
以
.do
作为后缀名。如果这里
(
本文的条件下
)
你不使用
.do
作为后缀名,
就没有程序来处理这个请求了。
因为
DispatcherServlet
将收到的请求转交给
SimpleUrlHandlerMapping
,
DispatcherServlet
收不到的请求,
SimpleUrlHandlerMapping
当然也收不到了。我们还定义了一个名为
HelloworldController
的
控制器来处理
/helloworld.do
的请求。大多数Web应用都会遇到需要填写表单的页面,当表单提交成功后,表单的数据被传送到Web服务器中处理,遇到这种情况Spring为我们提供了一个简单的类
SimpleFormController
。
代码清单2
import
javax.servlet.http.HttpServletRequest;
import
javax.servlet.http.HttpServletResponse;
import
org.springframework.web.servlet.mvc.SimpleFormController;
public
class
HelloworldController
extends
SimpleFormController{
public
HelloworldController(){
//
设置表单对象类型
this
.setCommandClass(User.
class
);
}
@Override
protected
void
doSubmitAction(Object command)
throws
Exception {
User user = (User)command;
//
将
User
对象存入数据库
}
}
代码清单
2
中我们将
HelloworldController
类继承
SimpleFormController
并且实现了
doSubmitAction
方法,在构造方法中我们设置了表单对象的类型,当表单提交后
Spring
会自动调用
doSubmitAction
方法将表单对象装配好作为入参传递进来,我们将其类型转后就可以对其操作了。
我的其它Spring文章,也许会对您有帮助
Spring的任务调度和邮件发送
Spring应用的单元测试
Spring的数据库支持
Spring的MVC框架
Spring的IoC容器
Spring对AOP的支持
Spring2.5注释驱动与基于注释的MVC