搜档网
当前位置:搜档网 › spring_mvc经典自学教程

spring_mvc经典自学教程

spring_mvc经典自学教程
spring_mvc经典自学教程

spring mvc学习教程(一)-入门实例

引言

1.MVC:Model-View-Control

框架性质的C层要完成的主要工作:封装web请求为一个数据对象、调用业务逻辑层来处理数据对象、

返回处理数据结果及相应的视图给用户。

2.简要概述springmvc

Spring C 层框架的核心是DispatcherServlet,它的作用是将请求分发给不同的后端处理器,也即使用

了一种被称为Front Controller 的模式(后面对此模式有简要说明)。Spring 的C 层框架使用了后端控

制器来、映射处理器和视图解析器来共同完成C 层框架的主要工作。并且spring 的C 层框架还真正地把

业务层处理的数据结果和相应的视图拼成一个对象,即我们后面会经常用到的ModelAndView 对象。

一、入门实例

1. 搭建环境

在spring的官方API文档中,给出所有包的作用概述,现列举常用的包及相关作用:org.springframework.aop-3.0.5.RELEASE.jar:与Aop编程相关的包

org.springframework.beans-3.0.5.RELEASE.jar:提供了简捷操作bean的接口

org.springframework.context-3.0.5.RELEASE.jar:构建在beans包基础上,用来处理资源文件及国际

化。

org.springframework.core-3.0.5.RELEASE.jar:spring核心包

org.springframework.web-3.0.5.RELEASE.jar:web核心包,提供了web层接口

org.springframework.web.servlet-3.0.5.RELEASE.jar:web 层的一个具体实现包,DispatcherServlet也位于此包中。

后文全部在spring3.0 版本中进行,为了方便,建议在搭建环境中导入spring3.0 的所有jar 包(所

有jar 包位于dist 目录下)。

2.编写HelloWorld实例

步骤一、建立名为springMVC_01_helloword,并导入上面列出的jar 包。

步骤二、编写web.xml配置文件,代码如下:

1.

2.

3. xmlns:xsi="https://www.sodocs.net/doc/3b4448444.html,/2001/XMLSchema-instance"

4. xsi:schemaLocation="https://www.sodocs.net/doc/3b4448444.html,/xml/ns/javaee

5. https://www.sodocs.net/doc/3b4448444.html,/xml/ns/javaee/web-app_2_5.xsd">

6.

7. spring

8. org.springframework.web.servlet.Dispatche

rServlet

9. 1

10.

11.

12. spring

13. *.do

14.

15.

16.

17.

复制代码

步骤三、建立spring-servlet.xml文件,它的命名规则:servlet-name-servlet.xml。它的主

要代码如下:

1.

2.

3.

4. xmlns:xsi="https://www.sodocs.net/doc/3b4448444.html,/2001/XMLSchema-instance"

xmlns:p="https://www.sodocs.net/doc/3b4448444.html,/schema/p"

5. xmlns:mvc="https://www.sodocs.net/doc/3b4448444.html,/schema/mvc"

xmlns:context="https://www.sodocs.net/doc/3b4448444.html,/schema/context"

6. xmlns:util="https://www.sodocs.net/doc/3b4448444.html,/schema/util"

7. xsi:schemaLocation="https://www.sodocs.net/doc/3b4448444.html,/schema/beans

https://www.sodocs.net/doc/3b4448444.html,/schema/beans/spring-beans-3.0.xsd

8. https://www.sodocs.net/doc/3b4448444.html,/schema/context

https://www.sodocs.net/doc/3b4448444.html,/schema/context/spring-context-3.0.xsd

9. https://www.sodocs.net/doc/3b4448444.html,/schema/mvc

https://www.sodocs.net/doc/3b4448444.html,/schema/mvc/spring-mvc-3.0.xsd

10. https://www.sodocs.net/doc/3b4448444.html,/schema/util

https://www.sodocs.net/doc/3b4448444.html,/schema/util/spring-util-3.0.xsd">

11.

12.

13. class="org.springframework.web.servlet.handler.SimpleUrl

HandlerMapping">

14.

15.

16.

key="/hello.do">helloControl

17.

18.

19.

20.

21.

22.

复制代码

步骤四、完成HelloWord.java的编写,代码如下:

1.package controller;

2.

3.import javax.servlet.http.HttpServletRequest;

4.import javax.servlet.http.HttpServletResponse;

5.

6.import org.springframework.web.servlet.ModelAndView;

7.import org.springframework.web.servlet.mvc.Controller;

8.

9.public class HelloWord implements Controller {

10. public ModelAndView handleRequest(HttpServletRequest request,

HttpServletResponse response)

11. throws Exception {

12. ModelAndView mav = new ModelAndView("hello.jsp");

13. mav.addObject("message", "Hello World!");

14. return mav;

15. }

16. }

17./*

18.* 说明:ModelAndView对象是包含视图和业务数据的混合对象,即是说通过此对象,我们

可以知道所

19.返回的相应页面(比如这里返回hello.jsp页面),也可以在相应的页面中获取此对象所

包含的业务数据

20.(比如这里message-hello worrld)。*/

21.

复制代码

步骤五、在当前项目web根目录下编写hello.jsp,主要代码如下:

1.<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

2.<%

3.String path = request.getContextPath();

4.String basePath =

request.getScheme()+"://"+request.getServerName()+":"+request.getServer

Port()+path+"/";

5.%>

6.

7.

8.

9.

10.

11.

12. My JSP 'hello.jsp' starting page

13.

14.

15.

16.

17.

18.

19.

22.

23.

24.

25.

26.获取值:${message}

27.

28.

29.

复制代码

步骤六:输入.../hello.do 进行测试。

如http://localhost/springmvc/hello.do

运行的结果是:获取值:Hello World!

4.简析spring mvc工作原理

(1)启动服务器,根据web.xml的配置加载前端控制器(也称总控制器)DispatcherServlet。在加载

时、会完成一系列的初始化动作。

(2)根据servlet的映射请求(上面的helloWorld实例中针对.do 请求),并参照“控制器

件”(即spring-servlet.xml这样的配置)文件,把具体的请求分发给特定的后端控制器进行处理(比

如上例会分发给HelloWorld控制器进行处理)

(3)后端控制器调用相应的逻辑层代码,完成处理并返回视图对象(ModelAndView)给前端处理器。

(4)前端控制器根据后端控制器返回的ModelAndView对象,并结合一些配置(后面有说明),返回一

个相应的页面给客户端。

小结:这种Front Controller模式常应用在主流的web框架中,比如典型的struts1.x框架.Front

Controller模式:所有请求先交给一个前端处理器(总控处理器)处理,然后前端处理器会参照一些配

置文件再把具体的请求交给相应的后端处理器。后端处理器调用逻辑层代码,并根据逻辑返回相应的视

图对象给前端控制器。然后前端控制器再根据视图对象返回具体的页面给客户端(提示:和spring mvc

一样,在struts1.x中前端控制器是Servlet,而在struts2中前端控制器是Filter)。概述Front Controller模式:前端控制器预处理并分发请求给后端控制器,后端控制器进行真正的逻辑处理并返回

视图对象,前端控器器根据视图对象返回具体页面给客户端。

5.初识spring mvc的视图

在前面的HelloWorld实例中,在HelloWorld.java中返回ModelAndView mav

=newModelAndView(

"hello.jsp") 参数为hello.jsp,它会对应于当前项目根目录下的hello.jsp页面。但spring mvc 为我们提供了

一个特别的视图定位方式,下面改进前面的HelloWord实例:

改进一:在spring-servlet.xml中增加如下代码:

1.

class="org.springframework.web.servlet.view.InternalResourceViewResolve

r">

2.

3.

4.

复制代码

改进二:在HelloWorld.java重新定义返回的ModelAndView对象,即把ModelAndView mav =new

ModelAndView("hello.jsp") 改为ModelAndView mav =newModelAndView("hello")

改进三:在/WEB-INF/page目录下建立hello.jsp页面

进行上面三个改进操作后,重新访问hello.do会访问到WEB-INF/page/hello.jsp页面。

简析视图定位:当返回ModelAndView对象名称为hello时,会给hello加上前后缀变成

/WEB-INF/page/hello.jsp。因此在给前后缀赋值时,应特别注意它和返回的ModelAndView

组成一个正确的文件全路径。在前面的“简析spring mvc工作原理(4)”点中提到在根

据ModelAndView对象返回页面时,会结合一些配置。这里就是结合了视图定位方式,给viewName

加上前后缀进行定位

spring mvc学习教程(二)-后端控制器(上)

1.概述SpringMVC后端控制器

为了方便开发人员快捷地建立适合特定应用的后端控制器,springMVC实现Controller接口,自定义了许多特定控制器。这些控制器的层次关系如下:

-AbstractController

-AbstractUrlViewController

-UrlFilenameViewController

-BaseCommandController

-AbstractCommandController

-AbstractFormController

-AbstractWizardFormController

-SimpleFormController

-CancellableFormController

-MultiActionController

-ParameterizableViewController

-ServletForwardingController

-ServletWrappingController

下面重点分析两个特色控制器:

2.SimpleFormController控制器

在正式开发前,请先熟悉上前面的HelloWord实例。在保证熟悉前一个实例后,我们建立

名为springMVC_02_controllerweb项目,并导入相关的jar包。

步骤一:建立后端控制器RegControl.java代码如下:

1.package controller;

2.

3.import javax.servlet.http.HttpServletRequest;

4.import javax.servlet.http.HttpServletResponse;

5.

6.import org.springframework.validation.BindException;

7.import org.springframework.web.servlet.ModelAndView;

8.import org.springframework.web.servlet.mvc.SimpleFormController;

9.

10.public class RegControl extends SimpleFormController{

11. @SuppressWarnings("deprecation")

12. public RegControl() {

13. setCommandClass(User.class);

14. }

15.

16. protected ModelAndView processFormSubmission(HttpServletRequest arg0,

HttpServletResponse arg1,

17. Object formbean, BindException arg3) throws Exception {

18. User user = (User) formbean;

19. ModelAndView mav = new ModelAndView("hello");

20. mav.addObject("message", "Hello World!");

21. mav.addObject("user", user);

22. return mav;

23. }

24.

25. protected ModelAndView showForm(HttpServletRequest arg0,

HttpServletResponse arg1, BindException arg2)

26. throws Exception {

27. return null;

28. }

29.}

复制代码

User.java,代码如下:

1.package controller;

2.

3.public class User {

4. private String username;

5. private int age;

6. public String getUsername() {

7. return username;

8. }

9. public void setUsername(String username) {

10. https://www.sodocs.net/doc/3b4448444.html,ername = username;

11. }

12. public int getAge() {

13. return age;

14. }

15. public void setAge(int age) {

16. this.age = age;

17. }

18.

19.}

复制代码

简要说明:如果熟悉struts1.x相信很容易理解Object formbean参数,其实它就是和表单属性打交道的一个对象,也即是说表单参数会依据一定的规则填充给formbean对象。在struts1.x中,如果像把这种与formbean转换成User对象,必须要求User继承自ActionForm 类,这样才能把一个表单参数转换成一个具体的formbean对象(所谓具体实质是指参数formbean对象已经能成功地赋值给User对象)并与相应的Action绑定。但springmvc并不要求这种User一定要继承某个类,既然springmvc对这种User没有要求,那表单参数是怎样与User进行完美匹配的,注意在RegControl构造方法中有如下一句代码:setCommandClass(User.class); 这句代码就指明了此控制器绑定User类来和表单进行匹配。如果想验证此句代码的作用,可以注释掉这句代码并查看异常。后面将会分析这种控制器的一个执行过程(包括表单填充及验证过程)

概述此步要点:(1)继承SimpleFormController类(2)构造器中调用setCommandClass 方法绑定定命令对象(这里为User类)(3)转换formbean为User类进行业务逻辑操作步骤二:配置web.xml(和前面HelloWorld实例一样,在此省略)

步骤三:配置spring-servlet.xml文件,代码如下:

1.

2.

3.

4. xmlns:xsi="https://www.sodocs.net/doc/3b4448444.html,/2001/XMLSchema-instance"

xmlns:p="https://www.sodocs.net/doc/3b4448444.html,/schema/p"

5. xmlns:mvc="https://www.sodocs.net/doc/3b4448444.html,/schema/mvc"

xmlns:context="https://www.sodocs.net/doc/3b4448444.html,/schema/context"

6. xmlns:util="https://www.sodocs.net/doc/3b4448444.html,/schema/util"

7. xsi:schemaLocation="https://www.sodocs.net/doc/3b4448444.html,/schema/beans

https://www.sodocs.net/doc/3b4448444.html,/schema/beans/spring-beans-3.0.xsd

8. https://www.sodocs.net/doc/3b4448444.html,/schema/context

https://www.sodocs.net/doc/3b4448444.html,/schema/context/spring-context-3.0.xsd

9. https://www.sodocs.net/doc/3b4448444.html,/schema/mvc

https://www.sodocs.net/doc/3b4448444.html,/schema/mvc/spring-mvc-3.0.xsd

10. https://www.sodocs.net/doc/3b4448444.html,/schema/util

https://www.sodocs.net/doc/3b4448444.html,/schema/util/spring-util-3.0.xsd">

11.

12.

13.

14.

id="viewResolver" class="org.springframework.web.servlet.view.Internal

ResourceViewResolver">

15.

16.

17.

18.

19.

id="simpleUrlHandlerMapping" class="org.springframework.web.servlet.h

andler.SimpleUrlHandlerMapping">

20.

21.

22. regControl

23.

24.

25.

26.

27.

28.

29.

复制代码

步骤四:根据配置文件完善相应页面

在index.jsp设定表单填写页面,主要代码如下:

1.<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

2.<%

3.String path = request.getContextPath();

4.String basePath =

request.getScheme()+"://"+request.getServerName()+":"+request.getServer Port()+path+"/";

5.%>

6.

7.

8.

9.

10.

11.

12. My JSP 'index.jsp' starting page

13.

14.

15.

16.

17.

18.

21.

22.

23.

24.

25.用户名:

26.年龄:

27.

28.

29.

30.

31.

复制代码

/page/hello.jsp,主要代码如下:

1.<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

2.<%

3.String path = request.getContextPath();

4.String basePath =

request.getScheme()+"://"+request.getServerName()+":"+request.getServer

Port()+path+"/";

5.%>

6.

7.

8.

9.

10.

11.

12. My JSP 'hello.jsp' starting page

13.

14.

15.

16.

17.

18.

19.

22.

23.

24.

25.

26.世界,你好!(WEB-INF/page)

27.用户名:${https://www.sodocs.net/doc/3b4448444.html,ername }

28.年龄:${user.age }

29.

30.

31.

复制代码

步骤五:启动服务器,访问到首页,填写表单完成测试。

spring mvc学习教程(三)-后端控制器(下)

3.细研SimpleController控制器

在RegControl.java中增加如下代码:

1.protected Object formBackingObject(HttpServletRequest request) throws

Exception {

2. System.out.println("formBackingObject方法执行-->01");

3. setCommandClass(User.class); //也可在此处调用

setCommandClass方法

4. return super.formBackingObject(request);

5. }

6.

7. protected void initBinder(HttpServletRequest request,

ServletRequestDataBinder binder) throws Exception {

8. System.out.println("initBinder方法执行-->02");

9. super.initBinder(request, binder);

10. }

11.

12. protected void onBind(HttpServletRequest request, Object command)

throws Exception {

13. System.out.println("onBind方法执行-->03");

14. super.onBind(request, command);

15. }

16.

17. protected void onBindAndValidate(HttpServletRequest request,

Object command, BindException errors)

18. throws Exception {

19. System.out.println("onBindAndValidate方法执行-->04");

20. super.onBindAndValidate(request, command, errors);

21. }

22.

复制代码

下面简要分析执行过程:

(1).当前端控制器把请求转交给此此控制器后,会首先调用formBackingObject方法,此方法的作用就是根据绑定的Command Class来创建一个Command对象,因此除了可以在构造方法中调用setCommandClass方法,也可以在此处调用setCommandClass方法。其实创建这个Command对象很简单,spring通过如下代码完成:

BeanUtils.instantiateClass(https://www.sodocs.net/doc/3b4448444.html,mandClass);

由于在此处必须根据commandClass来完成Command对象的创建,因此在此方法调用前应保证commandClass设置完成,所以我们可以在formBackingObject方法和构造方法中完成commandClass的设置。

(2).调用initBinder方法,初始化Command对象,即把表单参数与Command字段按名称进行匹配赋值。

(3).调用onBind方法,把Command对象和后端控制器绑定。

(4).调用onBindAndValidate方法,验证用户输入的数据是否合法。如果验证失败,我们可以通过修改errors参数,即新的errors对象将会绑定到ModelAndView上并重新回到表单填写页面。

(5).执行processFormSubmission方法,主要操作就是把绑定的Command对象转换成一个User这样的表单对象,并调用业务逻辑方法操作User对象,根据不同的逻辑返回不同的ModelAndView对象。

4.MultiActionController控制器

此控制器来将多个请求处理方法合并在一个控制器里,这样可以把相关功能组合在一起(它和struts1.x中的DispatchAction极为相似)。下面通过实例演示此控制器的使用。

步骤一:在springMVC_02_controllerweb项目下,建立后端控制器UserManagerController.java,代码如下:

1.package com.asm;

2.//...省略导入的相关类

3.public class UserManagerController extends MultiActionController {

4. public ModelAndView list(HttpServletRequest request,

HttpServletResponse response) {

5. ModelAndView mav = new ModelAndView("list");

6. return mav;

7. }

8.

9. public ModelAndView add(HttpServletRequest request,

HttpServletResponse response) {

10. ModelAndView mav = new ModelAndView("add");

11. return mav;

12. }

13.

14. public ModelAndView edit(HttpServletRequest request,

HttpServletResponse response) {

15. ModelAndView mav = new

ModelAndView("edit");

16. return mav;

17. }

18.

19.}

20.

复制代码

步骤二:配置web.xml(参前面实例),并在spring-servlet.xml中增加如下配置:

1.

id="springMethodNameResolver" class="org.springframework.

web.servlet.mvc.multiaction.PropertiesMethodNameResolver">

2.

3.

4. list

5. add

6. edit

7.

8.

9.

10.

11.

id="userManagerController" class="https://www.sodocs.net/doc/3b4448444.html,erManagerController">

12.

13. ref="springMethodNameResolver">

14.

15.

16.

复制代码

说明:methodNameResolver负责从请求中解析出需要调用的方法名称。Spring本身已经提供了一系列MethodNameResolver的实现,当然也可以编写自己的实现。在这里我们使用了Pro方式来解析,具体表现如下:

list 请求list.do时调用list方法

add 请求为add.do时调用add方法

edit 请求为edit.do时调用edit方法

然后通过把springMethodNameResolver解析器注入给UserManagerController的methodNameResolver,这样配置后才完成了一个真正的具有请求转发能力的MultiActionController控制器对象——UserManagerController 强调:此步骤实质完成了一个工作:就是为UserManagerController控制器配置一个方法解析器。

步骤三:配置请求转发的访问路径,在spring-servlet.xml中添加如下代码

1.

id="simpleUrlHandlerMapping" class="org.springframework.w

eb.servlet.handler.SimpleUrlHandlerMapping">

2.

3.

4.

key="/list.do">userManagerController

5.

key="/add.do">userManagerController

6.

key="/edit.do">userManagerController

7.

8.

9.

10.

复制代码

步骤四:根据配置文件,完善jsp页面编写。

page/list.jsp,代码如下:

用户列表页面

page/add.jsp,代码如下:

用户添加页面

page/edi.jsp,代码如下:

用户修改页面

步骤五:启动服务器,访问…/list.do将调用到list方法并转向到list.jsp页面。

补充:细说MethodNameResolver解析器

InternalPathMethodNameResolver:默认MethodNameResolver解析器,从请求路径中获取文件名作为方法名。比如,…/list.do的请求会调用

list(HttpServletRequest,HttpServletResponse)方法。ParameterMethodNameResolver:解析请求参数,并将它作为方法名。比如,对

应…/userManager.do?method=add的请求,会调用add(HttpServletRequest, HttpServletResponse)方法。使用paramName属性定义要使用的请求参数名称。PropertiesMethodNameResolver :使用用户自定义的属性(Properties)对象,将请求的URL映射到方法名,具体可以参见实例。

使用ParameterMethodNameResolver作为MethodNameResolver的解析器时,主要配置代码如下:

1.

id="simpleUrlHandlerMapping" class="org.springframework.w

eb.servlet.handler.SimpleUrlHandlerMapping">

2.

3.

4.

key="/user.do">userManagerController

5.

6.

7.

8.

9.

id="ParameterMethodNameResolver" class="org.springframewo

rk.web.servlet.mvc.multiaction.ParameterMethodNameResolver">

10.

11.

12.

13.

14. class="https://www.sodocs.net/doc/3b4448444.html,erManagerController">

15.

16. ref="ParameterMethodNameResolver">

17.

18.

19.

复制代码

访问路径为…/user.do?crud=list(add|edit)

spring mvc学习教程(四)-映射处理器(上)

Message:${message}

步骤五:启动服务器,输入…/message.do访问测试。

简析执行过程

(1)启动服务器后,当我们向服务器发送message.do请求时,首先被在web.xml 中配置的前端控制器DispatcherServlet拦截到。

(2)前端控制器把此请求转交给后端控制器,下面分析转交过程:当在

spmvc-servlet.xml中查找能执行message.do请求的映射处理器时,发现没有能处理此请求的映射处理器,这时便使用默认的映射处理器BeanNameUrlHandlerMapping:This is the default implementation used by

the DispatcherServlet, along

with DefaultAnnotationHandlerMapping (on Java 5 and higher).我们还需注意:这种后端控制器的bean Name必须以“/”开头,并且要结合DispatcherServlet的映射配置。同时beanName支持通配符配置。比如如果配置: 时,当访问messasge.do时也可以成功访问到MessageController类。

(3)BeanNameUrlHandlerMapping处理器,会查找在spring容器中是否在

名为“message.do”的bean实例。当查找到此实例后,则把此bean作为处理此请求的后端控制器。同时把自身加到映射处理器链上,并向处理器链传递此请求。(4)后端控制器进行处理,并返回视图

spring mvc学习教程(五)-映射处理器(下)

相关主题