什么是springMVC
springMVC是一个实现了mvc架构模式的web框架。底层基于servlet实现。
springMVC帮我们做了什么
springMVC帮我们做了什么?与传统的servlet开发有什么区别?
- 入口控制:springMVC通过DispatcherServlet作为入口控制器。负责接收请求和分发请求。而在servlet中。需要自己编写servlet程序,并在web.xml中配置,才能接收和处理请求。
- 在springMVC中,表单提交时可以自动将表单数据绑定到对应的JavaBean对象中。只需要在控制器方法的参数列表中声明该JavaBean对象即可。无需手动获取和赋值表单数据。而在servlet中需要手动完成。
- IoC容器:springMVC通过IOC容器管理对象。只需要在配置文件中进行相应的配置即可获取实例对象。而在servlet中需要手动创建对象实例。
- 统一处理请求:springMVC提供了拦截器、异常处理器等统一处理请求的机制。并且可以灵活的配置这些处理器。而在servlet中。需要自行编写过滤器、异常处理器等,增加了代码复杂度和开发难度。
- 视图解析:springMVC提供多种视图模板,如jsp、Freemarker等,并且支持国际化、主题等特性。而在servlet中需要手动处理视图,增加了代码复杂度。
第一个springmvc程序
- 引入依赖
xml
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>6.1.14</version>
</dependency>
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>6.1.0</version>
<!-- 指定依赖范围,provided表示依赖由第三方容器提供-->
<!-- 打war包的时候,这个依赖不会打进包内。-->
<scope>provided</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.5.25</version>
</dependency>
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring6</artifactId>
<version>3.1.2.RELEASE</version>
</dependency>
</dependencies>
- 在web.xml文件中配置:前端控制器(DispatcherServlet类),所有请求都应应该经过这个DispatcherServlet的处理。
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">
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<!-- / 表示:除xxx.jsp结尾的请求路径之外的所有请求路径-->
<!-- /* 表示:所有的请求路径-->
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
DispatcherServlet是springmvc最核心的类。他是springmvc的前端控制器,主要职责包括:
-
接收客户端的HTTP请求:DispatcherServlet监听来自web浏览器的HTTP请求。然后根据强求的url将请求数据解析为request对象
-
处理请求的url:DispatcherServlet将请求的url与处理程序进行匹配。确定要调用哪个controller来处理请求
-
调用相应的控制器:DispatcherServlet将强求发送给控制器处理。控制器执行业务逻辑。然后返回一个模型对象(Model)
-
渲染视图:DispatcherServlet调用视图引擎。将模型对象呈现为用户可以查看的html页面
-
返回响应给客户端:DispatcherServlet将响应发送回浏览器。响应包括表单、json、xml、html以及其他类型数据。
-
编写控制器
java// @Controller 纳入ioc容器管理, // @Controller 是@Component的别名 @Controller public class FirstController { @RequestMapping("/test") public String say(){ // 返回逻辑视图名称,会通过配置文件设置的前缀和后缀将逻辑视图解析成物理视图进行返回。 return "first"; } } -
编写springmvc配置文件(springmvc-servlet.xml)
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.ali.controller" /> <!-- 配置视图解析器--> <bean id="thymeleafViewResolver" class="org.thymeleaf.spring6.view.ThymeleafViewResolver"> <!-- 设置视图编码字符集--> <property name="characterEncoding" value="UTF-8" /> <!-- 如果配置多个视图解析器,它来决定优先使用哪个视图解析器,值越小优先级越高--> <property name="order" value="1" /> <!-- 使用该模板引擎来解析、编译、渲染模板--> <property name="templateEngine"> <bean class="org.thymeleaf.spring6.SpringTemplateEngine"> <!-- 指定thymeleaf使用的模板解析器。模板解析器负责根据模板位置、模板资源名称、文件编码等信息,加载模板并对其进行解析。--> <property name="templateResolver"> <bean class="org.thymeleaf.spring6.templateresolver.SpringResourceTemplateResolver" > <!-- 设置模板文件位置(前缀)--> <property name="prefix" value="/WEB-INF/templates/" /> <!-- 设置模板文件后缀,文件扩展名不一定是html。也可以是其他。比如txt。大部分是html--> <property name="suffix" value=".html" /> <!-- 设置模板类型--> <property name="templateMode" value="HTML" /> <!-- 设置编码字符集--> <property name="characterEncoding" value="UTF-8" /> </bean> </property> </bean> </property> </bean> </beans>
配置tomcat,启动tomcat后,访问http://localhost:8080/springmvc/test 。
执行流程总结:
-
springmvc前端控制器DispatcherServlet接收到请求
-
DispatcherServlet根据请求路径/test映射到FirstController,调用该方法
-
FirstController处理请求
-
FirstController返回视图逻辑名称first给视图解析器
-
视图解析器找到/WEB-INF/templates/first.html文件,并进行解析。生成视图解析对象返回给前端控制器DispatcherServlet
-
前端控制器DispatcherServlet响应结果到浏览器。
一个控制器里可以编写多个方法。
实现springmvc的首页功能
在controller里添加跳转首页的方法。请求路径设为"/"
java
@RequestMapping("/")
public String toIndex(){
return "index";
}
这样就会默认跳转到index.html这个首页里面,因为web.xml文件里配置了 / 属性。
指定springmvc配置文件的名字和路径
在web.xml文件中。可以如下配置
xml
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<!-- 指定springmvc配置文件的名字是springmvc.xml
指定springmvc配置文件存放的路径是类的根路径-->
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<!-- 在web服务器启动的时候,就初始化DispatcherServlet
这样在第一次访问请求的时候,速度就比较快-->
<load-on-startup>0</load-on-startup>
</servlet>
RequestMapping注解
RequestMapping的作用
@RequestMapping用于将请求映射到相应的处理方法上,可以将指定url的请求绑定到一个方法或者类上,从而实现对请求的处理和相应。
@RequestMapping可以标注在类和方法上。
在同一个web应用中,不允许有2个相同的RequestMapping,否则启动报错。
RequestMapping注解的value属性
value属性填写的是请求路径。value属性是一个字符串数组。表示可以提供多个路径。
也就是说,在springmvc中,可以将多个不同的请求路径映射到一个控制器的同一个方法上。
java
@RequestMapping({"/test01","/test_01","test1"})
public String testRequest(){
return "test_01";
}
ant风格的value(路径支持模糊匹配)
ant风格的value支持路径模糊匹配。关于路径中的通配符包括:
-
?:代表任意一个字符(除/ ? 之外的其他字符,不能空着)
-
*:代表0到n个任意字符(除/ ? 之外的其他字符)
-
** :代表0到n个任意字符,并且路径中可以出现路径分隔符/
注意: 通配符在使用时,左右不能出现字符,只能是/(spring5及以前的版本适用,spring6会报错)**
在spring6中 通配符只能出现在末尾。比如:/testAnt/****
java
@RequestMapping("/x?y/test")
public String testAntValue(){
return "test_ant";
}
value中的占位符
java
// restful风格的url
@RequestMapping("/test/restful/{id}/{name}")
public String testRestful(@PathVariable("id") int id,
@PathVariable("name") String name){
return "test_restful";
}
RequestMapping注解的method属性
用来指定请求方式。
method属性是一个数组,所以可以设置多种请求方式。
java
// 请求路径是/test/login,且请求方式是post
@RequestMapping(value = "/test/login", method = RequestMethod.POST)
public String testLogin(){
return "test_login";
}
衍生的Mapping
@PostMapping 默认采用post方式处理。
@GetMapping 默认采用get方式处理。
web的请求方式
- get(查):获取资源,不影响数据的状态和功能。使用url中传递参数,或者在HTTP请求的头部使用参数,服务器返回请求资源。
- post(增):向服务器提交资源,可能会改变数据的状态和功能。通过表单方式提交请求体。服务器接收请求体后,进行数据处理。
- put(改):更新资源,用于更新指定的资源上所有可编辑内容。通过请求体发送需要被更新的全部内容,服务器接收数据后,将被更新的资源进行修改或替换。
- delete(删):删除资源。用于删除指定的资源。将要被删除的资源标识符放在url中或请求体中。
- head:请求服务器返回资源的头部,与get类似。但是返回的信息是头部信息,不能包含数据体。主要用于资源检测和缓存控制。
- patch:部分更改请求。当请求的资源是可被更改的资源时,请求服务器对该资源进行部分更新,即每次更新一部分。
- options:请求获得服务器支持的请求方法类型。以及支持的请求头标志。"OPTIONS"则返回支持全部方法类型的服务器标志。
- trace:服务器响应客户端HTTP请求,主要用于调试和测试。
- connect:建立网络连接。通常用于加密ssl/TLS连接。
get与post的区别
| get | post |
|---|---|
| 数据会挂在url后面,并且在url后面添加一个?。数据会回显在浏览器地址栏 | 数据在请求体中,不会回显在浏览器地址栏 |
| 只能发送普通字符串,并且有长度限制,不同的浏览器限制不同 | 可以发送任何类型数据,包括字符串、流媒体等信息。理论上没有长度限制 |
| 适合从服务端获取数据 | 适合向服务端传送数据 |
| 请求是安全的,因为是获取数据 | 危险的。因为是修改服务器资源 |
| 支持缓存,二次请求会走浏览器缓存,不去请求真正的服务器 | 不支持缓存 |
RequestMapping注解的params属性
params用来设置请求参数映射。
params属性也是一个数组,要求请求参数必须和params数组中要求的所有参数完全一致后,才能映射成功。
RequestMapping注解的headers属性
headers和params原理相同。用法也相同。
当前端提交的请求头信息和后端要求的请求头信息一致时,才能映射成功。
java
// 请求路径是/test/headers,且请求头中必须包含Referer和Host
@RequestMapping(value = "/test/headers", headers = {"Referer", "Host"})
public String testHeaders(){
return "test_headers";
}