Spring的MVC框架

第一章    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方法将表单对象装配好作为入参传递进来,我们将其类型转后就可以对其操作了。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,864评论 6 494
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,175评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,401评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,170评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,276评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,364评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,401评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,179评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,604评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,902评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,070评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,751评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,380评论 3 319
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,077评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,312评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,924评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,957评论 2 351

推荐阅读更多精彩内容