第 5 章 基础 学习目的与学习要求 学习目的:了解SpringMVC框架,掌握SpringMVC 框架的工作流程及组件,熟悉SpringMVC原理,包括核心 控制器DispatcherServlet、Controler控制器、ModelAndView 和视图解析ViewResolver等。 学习要求:熟练搭建和开发基于SpringMVC框架的 应用系统,顺利完成本章案例的开发,并能够开发项目的其 他功能。 本章主要内容 本章主要内容包括MVC模式的概述、MVC与SpringMVC的映射、SpringMVC框架的工作流程和组件、SpringMVC原理(包括核心控制器DispatcherServlet、Controler 控制器、ModelAndView和视图解析ViewResolver等)以 及SpringMVC开发步骤。 SpringMVC框架是MVC设计模式的一个具体实现, 所以先介绍MVC模式。 5.MVC模式概述 1 计算机软件工程领域常常提到设计模式(Design Patern)。那么,什么是模式(Patern)呢? 一般来说,模式 是指一种从一个一再出现的问题背景中抽象出的解决问题 的固定方案,而这个问题背景不应该是绝对的,或者说是不 固定的。很多时候看来不相关的问题,会有相同的问题背 景,从而需要应用相同的模式解决。 模式的概念开始时出现在城市建筑领域中。后来,这 个概念逐渐被计算机科学所采纳,并在一本广为接受的经 Java高级框架应用开发与项目案例教程———Spring+SpringMVC+MyBatis 典书籍的推动下流行起来。这本书就是DignPtes:EltfRbleObject- OitdSfte(设计模式:可复用面向对(e) 象(s) 软件元(a) 素),(n) (r) 由4位(e) 软(e) 件大(so) (n) 师合(e) 写(s) 而成((a) (m) 很多 时候(r) 直(n) 接(e) 用G(o) oF(wa) 指(r) 这4位作者,GoF的意思是GangsofFour,即四人帮)。 设计模式指的是在软件的建模和设计过程中运用到的模式。设计模式中的很多种方 法其实很早就出现了,并且应用得也比较多。但是,直到GoF的书出来之前,并没有一种 统一的认识。或者说,那时对模式并没有形成一个概念,这些方法还仅处在经验阶段,并没 有被系统地整理,形成一种理论。 每个设计模式都系统地命名、解释和评价了面向对象系统中一个重要的和重复出现的 设计。这样,只要清楚这些设计模式,就可以完全或者说很大程度上吸收那些蕴含在模式 中的宝贵经验,对面向对象的系统能够有更完善的了解。更重要的是,这些模式都可以直 接用来指导面向对象系统中至关重要的对象建模 问题。如果有相同的问题背景,直接套用这些模式 就可以了,这可以省去很多工作量。 MVC模式是一种很常见的设计模式。所谓的 MVC模式,即模型-视图-控制器(Model-View- Controler)模式。MVC架构图如图5-1所示。图5-1 MVC 架构图 1.Model端 在MVC中,模型是执行某些任务的代码,而这部分代码并没有任何逻辑决定用户端 的表示方法。Model只有纯粹的功能性接口,也就是一系列的公共方法,通过这些公共方 法,可以取得模型端的所有功能。 2.View 端 在MVC模式里,一个Model可以有几个View端,而实际上多个View端是使用 MVC的原始动机。使用MVC模式可以允许多于一个的View端存在,并可以在需要的时 候动态注册需要的View。 3.Controler端 MVC模式的视图端是与MVC的控制器结合使用的。当用户端与相应的视图发生交 互时,用户可以通过视窗更新模型的状态,而这种更新是通过控制器端进行的。控制器端 通过调用模型端的方法更改其状态值。与此同时,控制器端会通知所有注册了的视图刷新 用户界面。 那么,使用MVC模式有哪些优点呢?MVC通过以下3种方式消除与用户接口和面 向对象的设计有关的绝大部分困难: (1)控制器通过一个状态机跟踪和处理面向操作的用户事件。这允许控制器在必要 时创建和破坏来自模型的对象,并且将面向操作的拓扑结构与面向对象的设计隔离开。这 个隔离有助于防止面向对象的设计走向歧途。 (2)MVC将用户接口与面向对象的模型分开。这允许同样的模型不用修改,就可使 用许多不同的界面显示方式。除此之外,如果模型更新由控制器完成,那么界面就可以跨 应用再使用。 第 5 章SpringMVC基础 (3)MVC允许应用的用户接口进行大的变化而不影响模型。每个用户接口的变化将 只需要对控制器进行修改,但是控制器包含很少的实际行为,它是很容易修改的。 面向对象的设计人员在将一个可视化接口添加到一个面向对象的设计中时必须非常 小心,因为可视化接口的面向操作的拓扑结构可以大大增加设计的复杂性。 MVC设计允许一个开发者将一个好的面向对象的设计与用户接口隔离开,允许在 同 样的模型中容易地使用多个接口,并且允许在实现阶段对接口做大的修改,而不需要对 相 应的模型进行修改 。 5.rngMVC概述 2 Spi SpringMVC属于SpringFramework的后续产品,已经融合在SpringWebFlow里。 SpringMVC分离了控制器、模型对象、分派器以及处理程序对象的角色,这让它们更容易 进行定制。 Spring的模型-视图-控制器(MVC)框架核心是围绕一个DispatcherServlet设计的, 这 个Servlet会将来自客户端的HTTP请求分发给各个用户自定义开发的处理器,同时支 持 可配置的处理器映射关系、页面视图的渲染、消息本地化和国际化,以及时区设置与页面 风 格主题渲染等 。 处理器被称为Controler,是在开发应用中注解了@Controler和@RequestMapping 的Java类和方法。由于SpringMVC作为Spring的WebMVC开发组件内置在Spring 中,所以Spig为SpigMVC的处理器方法提供了极其多样灵活的配置。Spig3. rnrnrn0以 后提供了@Controler注解机制、@PathVariable注解,以及一些其他的特性,使得开发更 加灵活、简洁,同时也可以使用SpringMVC进行RESTfulWeb站点和应用的开发。 在SpringWebMVC中,可以使用任何Java对象作为执行请求处理的命令对象或表 单数据处理的返回对象,而无须实现与框架相关的接口或基类。Spring的数据绑定非常灵 活:例如,它会把数据类型不匹配当成可由应用自行处理的运行时验证错误,而非系统错 误。之前你可能会为了避免非法的类型转换,在表单对象中使用字符串存储数据,但无类 型的字符串无法描述业务数据的真正含义,并且还需要把它们转换成对应的业务对象类 型。有了Spring的验证机制,再也不必这么做了,直接将业务对象绑定到表单对象上通常 是更好的选择。 Spring的视图解析设计得也异常灵活。控制器一般负责准备一个Map模型、填充数 据、返回一个合适的视图名等,同时它也可以直接将数据写到响应流中。视图名的解析高 度灵活,支持多种配置,包括通过文件扩展名、Acept内容头、Bean、配置文件等的配置,甚 至还可以自己实现一个视图解析器ViewResolver。模型(Model)其实是一个Map类型的 接口,彻底地把数据从视图技术中抽象分离了出来。可以与基于模板的渲染技术直接整 合,如JSP 、Velocity和Fremarker等,也可以直接生成XML 、JSON 、Atom以及其他多种 类型的内容。Map模型会简单地被转换成合适的格式,如JSP的请求属性(atribute)、一 个Velocity模板的模型等。 Java高级框架应用开发与项目案例教程———Spring+SpringMVC+MyBatis 5.MVC组件和流程 3 SpringMVC体系结构实现了Model-View-Controler设计模式的概念,它将这些概念 映射到Web应用程序的组件和概念中。 SpringMVC对于URL请求的处理框架如图5-2所示。 图5-2 Spring MVC 的体系概图 上述的架构图中包括了SpringMVC中的核心功能组件的定义。 (1)DispatcherServlet:SpringMVC提供的前端控制器,所有的请求都经过它识别, 以及负责统一请求分发和响应处理。如logn.cin这样的URL请求信息,首先需要 iatoDispatcherServlet识别请求,然后根据配置信息在HandlerMapping中查找处理该URL的 具体的Java类和相应的处理方法。 (2)HandlerMapping:保存了URL与ControlerJava类和方法的映射关系, DispatcherServlet需要借助该对象定位具体的Java对象和方法,以便处理URL请求。 (3)Controler:被标记和实现为Controler的类通过内部定义的Java方法,为并发发 出同样URL请求的用户处理每个请求,因此实现Controler接口时,须保证线程安全并且 可重用。Controler类将调用对应URL的Java方法处理用户请求,并由开发人员决定是 否使用ModelAndView。一旦Controler中的Java方法处理完用户请求,则由开发人员决 定使用怎样的方式返回ModelAndView对象给DispatcherServlet前端控制器。 (4)ModelAndView:包含了模型(Model)和视图(View)。模型是处理之后需要展示 或者传递到View中的数据,如用户信息、登录消息等。View负责展示动态数据的各种页 面技术,如JSP 、PDF 、XML 、JSON格式(JavaScript中的数据对象)等。 第 5 章SpringMVC基础 (5)ViewResolver:Spring提供的视图解析器(ViewResolver)在Web应用中查找 View(数据展示视图)对象,从而将相应模型中的数据与视图进行渲染(解析处理),最后将 渲染后的结果返回给客户端。 从框架设计整体来说,DipaceSrlt是整个Web应用的控制器, exm sthreve需要在wb.l 中配置;Controler是针对具体某个URL的单个Htp请求处理过程中的控制器,是需要 开发与配置的Java类;而ModelAndView是包含了处理Htp请求过程中的需要返回客户 端的数据模型(Model)和在客户端需要展现数据方式的视图(View)两部分内容。 这些对象在SpringMVC框架中相互配合,用于处理来自客户端的请求,其主要工作 流程如下: ①客户端请求提交到DispatcherServlet。 ②由DispatcherServlet控制器查询一个或多个HandlerMapping,找到处理请求的 Controler。 ③DispatcherServlet将请求提交到Controler。 ④Controler调用业务逻辑处理后,返回ModelAndView。 ⑤DispatcherServlet查询一个或多个ViewResoler视图解析器,找到ModelAndView 指定的视图。 ⑥视图负责将结果显示到客户端。 先看一个用MyEclipse开发的SpringMVCWeb应用heloworld实例,接下来将详细 讲解相关理论内容。 (1)新建一个Web项目,项目名称为SpringMVC_HeloWorld_demo 。 选择File→New→WebProject命令,如图5-3所示 。 图5-3 新建Web Project 在Projectname中命名为SpringMVC_HeloWorld_demo,如图5-4所示。 单击Next按钮,保持默认配置,之后再单击Next按钮,勾选Generateweb.xml deploymentdescriptor,如图5-5所示。 Java高级框架应用开发与项目案例教程———Spring+SpringMVC+MyBatis 图5-4 命名Web Project 图5-5 勾选Generate web.xml deployment descriptor 最后单击Finish按钮。 (2)添加SpringMVC相关jar包。右击SpringMVC_HeloWorld_demo项目,从弹 出的快捷菜单中选择ConfigureFacets. →InstalSpringFacet,如图5-6所示。 之后出现图5-7。 保持默认设置,单击Next按钮,出现图5-8。 保持默认设置,单击Next按钮,出现图5-9。 不需修改(这里需要Sprig4.0Lirres中的Cre、aes和Sprnar包), 单击Finish按钮。 n1.baioFctigWebj 第5章 SpringMVC 基础 图5-6 Install Spring Facet 界面1 图5-7 Install Spring Facet 界面2 Java高级框架应用开发与项目案例教程———Spring+SpringMVC+MyBatis 图5-8 Install Spring Facet 界面3 图5-9 Install Spring Facet 界面4 (3)建立项目目录。 右击src,从弹出的快捷菜单中选择New→Package,如图5-10 所示。 命名包名为com.ascent,如图5-11 所示,之后单击Finish按钮。 我们将在这个包里存放Java代码。 第 5 章 SpringMVC基础 10 9 图5-10 新建Package 图5-11 命名Package (4)修改web.xml,添入以下内容。 helloWorld org.springframework.web.servlet.DispatcherServlet Java高级框架应用开发与项目案例教程———Spring+SpringMVC+MyBatis 11 0 1 helloWorld / 这里将DispatcherServlet命名为helloWorld,并且让它在Web项目一启动就加载。 接下来需要在WEB-INF目录下创建一个helloWorld-servlet.xml的Spring配置文件,此 文件名的命名规则为:在servlet-name名称后面加上-servlet.xml。 (5)添加helloWorld-servlet.xml配置文件,内容如下。 添加了mvc名称空间,接下来启用了Spring的自动扫描,并且设置了默认的注解映射 支持。其中base-package="com.ascent"是我们之前建立的package名。 配置文件中的Bean的类型是SpringMVC中最常用的一种视图解析器。prefix属性 是指视图前缀,suffix是视图后缀,这里配置的是.jsp,我们在控制器的方法sayHello()中 返回的是hello,结合这里的配置,对应的完整的视图是/WEB-INF/views/hello.jsp。 (6)编写HelloWorldController文件。 右击com.ascent包,从弹出的快捷菜单中选择New→Class,如图5-12所示。 在Name处填入HelloWorldController,单击Finish按钮,如图5-13所示。