一、SpringMVC简介
SpringMVC:是基于spring的一个框架, 实际上就是spring的一个模块, 专门是做web开发的,理解是servlet的一个升级
web开发底层是servlet , 框架是在servlet基础上面加入一些功能,让你做web开发方便
SpringMVC就是一个Spring
Spring是容器,ioc能够管理对象,使用<bean>,@Component,@Repository,@Service,@Controller
SpringMVC能够创建对象, 放入到容器中(SpringMVC容器), springmvc容器中放的是控制器对象,我们要做的是 使用@Contorller创建控制器对象, 把对象放入到springmvc容器中, 把创建的对象作为控制器使用这个控制器对象能接收用户的请求, 显示处理结果,就当做是一个servlet使用
- 使用@Controller注解创建的是一个普通类的对象, 不是Servlet。 springmvc赋予了控制器对象一些额外的功能
web开发底层是servlet, springmvc中有一个对象是Servlet : DispatherServlet(中央调度器)
DispatherServlet: 负责接收用户的所有请求, 用户把请求给了DispatherServlet, 之后DispatherServlet把请求转发给我们的Controller对象, 最后是Controller对象处理请求
二、第一个注解的SpringMVC程序
所谓 SpringMVC 的注解式开发是指,在代码中通过对类与方法的注解,便可完成处理器在 springmvc 容器的注册。注解式开发是重点
完成功能:用户提交一个请求,服务器处理器在接收到这个请求后,给出一条欢迎信息,在响应页面中显示该信息
1. 新建maven web项目
可以看之前写的完整建项目过程
https://www.cnblogs.com/mengd/p/13436355.html
或这样,先建立一个空的项目
然后在这个空项目里建立module
创建成功:
由于文件目录有缺少,这时哦我们自己添加必要的目录,并转换为对应的
2. pom.xml
加入Servlet依赖和SpringMVC依赖
下面是完整的pom.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.md</groupId>
<artifactId>01-hello-springmvc</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<!-- servlet的依赖-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!-- springmvc的依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
</dependencies>
<build>
</build>
</project>
3. 注册中央调度器
打开web.xml文件,默认的是这样的
由于这个版本太低了,所以需要换成这样的,可以直接复制之前写的,粘贴到这就可以了
主要内容看下面写的注释
在web.xml文件里
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!-- 声明,注册springmvc的核心对象DispatcherServlet
需要是tomcat服务器启动之后,创建DispatcherServlet对象的实例
why?
因为DispatcherServlet在它创建的过程中,会同时创建springmvc容器对象,
读取springmvc的配置文件,把这个配置文件中的对象都创建好,
当用户发起请求的时候就可以直接的调用对象了
原理:
servlet的初始化会执行init()方法。 DispatcherServlet在init()中{
//创建容器,读取配置文件
WebApplicationContext ctx = new ClassPathXmlApplicationContext("springmvc.xml");
//把容器对象放入到ServletContext中
getServletContext().setAttribute(key,ctx);
}
启动tomcat报错,读取这个文件 /WEB-INF/springmvc-servlet.xml(/WEB-INF/myweb-servlet.xml)
springmvc创建容器对象时,读取的配置文件默认是/WEB-INF/<servlet-name>-servlet.xml .
-->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--自定义springmvc的配置文件的位置-->
<init-param>
<!--springmvc的配置文件的位置属性-->
<param-name>contextConfigLocation</param-name>
<!--指定自定义文件的位置,也就是resources目录下-->
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<!-- 在Tomcat启动后,创建Servlet对象
load-on-startup:表示tomcat启动后创建对象的顺序,值是整数,
值越小(>=0),tomcat创建对象的时间越早,
-->
<load-on-startup>1</load-on-startup>
</servlet>
<!--用户使用.do的请求都经过这里 -->
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<!--
使用框架时,url-pattern可以有两种值
1. 扩展名 *.xxx , xxx是扩展名,例如:*.do,*.action等,(建议)
2. 使用 "/"
-->
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<!-- 以上内容几乎每个项目都要用,需要改的就是自定义文件的位置和url-pattern-->
</web-app>
4. 创建SpringMVC配置文件
在工程的类路径即 src 目录下resources下创建 SpringMVC 的配置文件 springmvc.xml,
该文件名可以任意命名,但由于我们在注册中央调度器的指定了名字,所以这里用springmvc.xml
5. 创建处理器
在类上与方法上添加相应注解即可
@Controller:表示当前类为处理器
@RequestMapping:表示当前方法为处理器方法。该方法要对 value 属性所指定的 URI进行处理与响应。被注解的方法的方法名可以随意
在src/main/java/com.md.controller的下面建立MyController类作为处理器
package com.md.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
/**
* @author MD
* @create 2020-08-12 9:21
*/
// @Controller:创建处理器对象,放在了springmvc的容器中
@Controller
public class MyController {
// 处理用户提交的请求,springmvc中使用方法来处理
// 方法是自定义的,可以有多种返回值,多种参数,方法名称自定义
/**
* 准备使用doSome方法处理some.do的请求
* @RequestMapping:请求映射,
* 作用是把一个请求的地址和一个方法绑定在一起
* 一个请求指定一个方法处理
* 属性:
* 1. value:是一个String,就是页面的请求地址,value的值必须唯一,使用时,推荐"/"开头
*
* 位置:
* 1. 在方法的上面:使用@RequestMapping修饰的方法叫做处理器方法或者控制器方法
* 2. 在类的上面
*
*
*
* 返回值:ModelAndView
* Model:数据,请求处理完成之后,要显示给用户的数据
* View:视图,比如jsp
*/
// 还可以让多个地址执行这一个方法
// @RequestMapping(value = {"/some.do","/other.do"})
@RequestMapping(value = "/some.do")
public ModelAndView doSome(){
// 在这个方法中就可以处理some.do的请求了
// 通常这个时候该调用service了,这里就相当于service的调用完成了
// 添加数据,框架在请求的最后把数据放入到request作用域中
// 相当于request.serAttribute("msg","欢迎使用springmvc");
ModelAndView mv = new ModelAndView();
mv.addObject("msg","欢迎使用springmvc");
mv.addObject("fun","执行的是doSome方法");
// 指定视图
// 相当于请求转发
mv.setViewName("/show.jsp");
return mv;
}
}
Model 中的数据存储在 request 作用域中,SringMVC 默认采用转发的方式跳转到视图,本次请求结束,模型中的数据被销毁
6. 声明组件扫描器
在 springmvc.xml 中注册组件扫描器
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!--声明组件扫描器
base-package:处理器所在的包
-->
<context:component-scan base-package="com.md.controller"/>
</beans>
7. 定义目标页面
在 webapp 目录新建一个 jsp 页面 show.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>show.jsp</h1>
这些都是从request作用域获取到的数据
<h2>msg:${msg}</h2>
<h2>fun: ${fun}</h2>
</body>
</html>
这里的数据就是通过处理器转发过来获取到的数据
8. 修改视图解析器的注册
SpringMVC 框架为了避免对于请求资源路径与扩展名上的冗余,在视图解析器InternalResouceViewResolver 中引入了请求的前辍与后辍。而 ModelAndView
中只需给出要@R_261_404@面的文件名即可,对于具体的文件路径与文件扩展名,视图解析器会自动完成拼接
在springmvc.xml中
主要注意前缀和后缀
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!--声明组件扫描器-->
<context:component-scan base-package="com.md.controller"/>
<!--声明springmvc框架中的视图解析器,帮助开发人员设置视图文件路径-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--前缀:视图文件的路径-->
<property name="prefix" value="/WEB-INF/view/" />
<!--后缀:视图文件的扩展名-->
<property name="suffix" value=".jsp"/>
</bean>
</beans>
此时把目标页面放入到/WEB-INF/view/下面
此时项目的目录是这样的
9. 修改处理器
这个时候直接写目标页面的名字即可,不用写路径和后缀
@Controller
public class MyController {
@RequestMapping(value = "/some.do")
public ModelAndView doSome(){
ModelAndView mv = new ModelAndView();
mv.addObject("msg","执行的是doSome方法");
// 指定视图
// 相当于请求转发
//mv.setViewName("/show.jsp");
mv.setViewName("show");
return mv;
}
}
10. 主页面
也就是index.jsp页面,
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<p>第一个springmvc项目</p>
<p> <a href="some.do">发起some.do的请求</a> </p>
</body>
</html>
此时,配置一下Tomcat这个程序就能运行了,点击 发起some.do的请求 就会跳转到show.jsp页面,并且还可以看到下面的页面
三、使用SpringMVC框架web请求处理顺序
四、SpringMVC执行流程
1. 流程图
2. 执行流程简单分析
- 浏览器提交请求到中央调度器
- 中央调度器直接将请求转给处理器映射器
- 处理器映射器会根据请求,找到处理该请求的处理器,并将其封装为处理器执行链后返回给中央调度器
- 中央调度器根据处理器执行链中的处理器,找到能够执行该处理器的处理器适配器
- 处理器适配器调用执行处理器
- 处理器将处理结果及要跳转的视图封装到一个对象 ModelAndView 中,并将其返回给处理器适配器
- 处理器适配器直接将结果返回给中央调度器
- 中央调度器调用视图解析器,将 ModelAndView 中的视图名称封装为视图对象
- 视图解析器将封装了的视图对象返回给中央调度器
- 中央调度器调用视图对象,让其自己进行渲染,即进行数据填充,形成响应对象
- 中央调度器响应浏览器