SpringMVC简介
SpringMVC是基于Spring的一个框架,实际上是Spring的一个模块,专门用来进行web开发。
web开发的底层是servlet,springmvc中有一个对象是Servlet:DispatherServlet(中央调度器),中央调度器负责接收用户的所有请求,用户把请求给调度器,调度器再把请求转发给我们的Controller对象,最后Controller对象处理请求。
Spring是容器,ioc能够管理对象,使用注解SpringMVC能够创建对象,放入容器中,SpringMVC容器中放的是控制器对象,,使用@Controller创建控制器对象,把对象放入SpringMVC容器,此时,可以用创建的对象来接收用户的请求,显示处理结果,当作一个servlet使用。
一个注解的SpringMVC程序
SpringMVC的注解式开发是指通过对类和方法进行注解,可以完成处理器在SpringMVC容器的注册。
(1)在pom.xml文件中加入依赖和插件:
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
</dependencies>
<build>
<plugins>
<!-- 编码和编译和JDK版本 -->
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
(2)在web.xml文件中注册中央调度器:
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
load-on-startup标签是标记启动web项目时,是否启动这个servlet实例,也就是是否调用执行该servlet的init()方法,而不是在真正访问时创建,它是一个整值。
值大于0的时候,容器启动就加载并初始化这个servlet,数值越小,该servlet的启动优先级就越高;
当值小于0或者没有指定的时候,只有servlet在真正使用的时候才会去创建;
当值相同的时候,容器会自动选择创建顺序。
url-pattern可以使用两个值,一个是扩展名方式,可以使用*.html,*.do等;另外一个则是使用斜杆方式“/”
(3)配置文件位置和名称
中央调度器注册完毕之后,可以在服务器上发布运行,访问浏览器页面控制器会抛出FileNotFoundException异常,默认找WEB-INF目录下的名为-servlet.xml的配置文件,这里的servlet名称指的是注册中央调度器标签中指定的servlet的name值。
一般情况下,配置文件应该在类路径下,也就是resources目录下,所以在注册中央调度器时,需要设置springmvc的文件路径还有文件名。
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<!--自定义springmvc读取配置文件的位置-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
(4)创建处理器
在类和方法上添加注解,@Controller表示当前类为处理器。@RequestMapping表示当前方法的处理器方法,该方法应该对value属性所指定的url进行处理和响应。
@Controller
public class MyController {
/**
* 处理用户提交的请求,springmvc中是使用方法来处理的
* 方法是自定义的,可以有多种返回值
*/
/**
* @RequestMapping:请求映射,作用是把一个请求地址和一个方法绑定在一起
* 一个请求指定一个方法处理
* 属性:
* 1、value是一个String类型的,表示请求的地址(addUser.html)
*
* 说明:使用RequestMapping修饰的方法叫做处理器方法或者控制器方法,
* 它作用类似Servlet中的doGet(),doPost()方法
*
* 返回值:ModelAndView,表示请求的处理结果
* Model:请求处理完显示给用户的数据
* View:视图,比如jsp等等
*/
@RequestMapping(value = "/addUser.do")
public ModelAndView addUser(){
//该方法addUser.html的请求,这里不在调用service请求处理了,
// 直接相当于service调用处理完成了
ModelAndView mv = new ModelAndView();
//添加数据
//框架在请求的最后把数据放入到request作用域中
//request.setAttribute("zs","张三");
mv.addObject("zs","张三");
mv.addObject("lisi","李四");
//指定视图的完整路径
//框架对视图执行的转发操作
//request.getRequestDispather("/jsp/show.jsp").forward(request,response);
//mv.setViewName("/jsp/show.jsp");
//mv.setViewName("/WEB-INF/jsp/show.jsp");
//当配置了视图解析器
//框架会使用视图解析器的(前缀+文件名+后缀)组成完整路径
// /WEB-INF/jsp/+show+.jsp
mv.setViewName("show");
//返回视图
return mv;
}
@RequestMapping(value = {"/remove.html","/remove1.html"})
public ModelAndView removeUser(){
ModelAndView mv = new ModelAndView();
mv.addObject("zs","删除张三");
mv.addObject("lisi","删除李四");
mv.setViewName("show");
return mv;
}
}
- 有多个请求路径匹配处理器方法的执行,value可以写上一个数组。
- ModelAndView类中的addObject()方法用于向Model中添加数据,Model底层是一个HashMap。
- Model中的数据存储在request作用域中,SpringMVC默认采用转发跳转到视图,本次请求结束,模型中的数据会被销毁。
(5)创建SpringMVC配置文件:
<!--声明组件扫描器-->
<context:component-scan base-package="com.hcz.controller"/>
(6)定义目标页面:
在webapp目录下新建一个jsp文件
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>显示页面</title>
</head>
<body>
<h3>显示用户姓名</h3><br>
<p>姓名:${zs}</p><br>
<p>姓名:${lisi}</p>
</body>
</html>
(7)修改SpringMVC的配置文件:
springmvc框架中为了避免请求策略与扩展名上的冗余,在InternalResouceViewResolver(视图解析器)中引入前缀和后缀,而ModelAndView中只需要给出跳转页面的文件名即可,对于具体的文件路径和文件扩展名,视图解析器会自动完成拼接。
<!--声明视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--前缀:视图文件路径-->
<property name="prefix" value="/WEB-INF/jsp/"/>
<!--后缀:视图文件扩展名-->
<property name="suffix" value=".jsp"/>
</bean>
使用springmvc框架web请求处理程序
- 用户发起addUser.do请求
- tomcat服务器通过web.xml配置文件中的DispatcherServlet的url-pattern将后缀名为.do的文件交给DispatcherServlet
- DispatcherServlet根据spring.xml配置文件组件扫描器知道@RequestMapping(value=“add User.do”)
- DispatcherServlet把addUser.do转发给MyController的addUser()方法处理
- 框架执行addUser()方法把得到的ModelAndView进行处理,转发到show.jsp
SpringMVC执行流程
- 浏览器发起请求some.do到中央调度器
- 中央调度器接受请求,把请求交给处理器映射器(springmvc框架的一种对象,框架实现了HadlerMapping接口的类叫映射器)(处理映射器会根据请求,从springmvc容器对象中获取处理器对象)(Mycontroller controller = ctx.getBean(“some.do”),框架把找到的处理器对象放入到一个叫处理器执行链(HandlerExceptionChain)的类中保存)(处理器执行链的类保存着处理器对象,项目中的拦截器)
- 中央调度器把执行链的处理器对象交给处理器的适配器(springmvc框架中的对象,需要实现HandlerAdapt接口)(执行处理器方法会得到返回值)
- 中央处理器把ModelAndView交给视图解析器对象
- 中央处理器把创建好的View对象获取到,调用View类自己的方法,把Model数据放入到request作用域中,执行forward,请求结束
执行过程分析
- 通过load-on-start标签指定的1,创建DisaptcherServlet对象
- DisaptcherServlet它的父类是继承HttpServlet,在被创建时,会执行init方法
- 在init方法中,创建容器,读取配置文件:
WebApplicationContext ctx = new ClassPathXmlApplicationContext("springmvc.xml");
- 把容器放入到ServletContext中:
getServletContext().setAttribute(key, ctx);
- 容器创建完成后,创建@controller注解所在类的对象,把创建的对象放入到springmvc容器(map)中,类似map.put(“myController”,MyController对象)
- (请求处理过程):执行servlet的service()
protected void service(HttpServletRequest request, HttpServletResponse response)
protected void doService(HttpServletRequest request, HttpServletResponse response)
DispatcherServlet.doDispatch(request, response){
调用MyController的.addUser( )方法
}