[SSM]SpringMVC 详解 @RequestMapping 注解获取请求参数和域数据共享
Posted Spring-_-Bear
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[SSM]SpringMVC 详解 @RequestMapping 注解获取请求参数和域数据共享相关的知识,希望对你有一定的参考价值。
SpringMVC
一、SpringMVC 介绍及示例
1. MVC 及 SpringMVC 的简介与特点
MVC 是一种软件架构的思想,将软件按照模型、视图、控制器来划分,分为 M(
model
)、V(view
)、C(controller
)
- M(
Model
):模型层,指工程中的 JavaBean,作用是处理数据。JavaBean分为两类:
1.1 一类称为实体类 Bean:用于存储业务数据,如 Student、User 等
1.2 一类称为业务处理 Bean:指Service
或Dao
对象,专门用于处理业务逻辑和数据访问- V(
View
):视图层,指工程中的html
或JSP
等页面,作用是与用户进行交互,展示数据- C(
Controller
):控制层,指工程中的 servlet,作用是接收请求和响应浏览器MVC 的工作流程:用户通过视图层(
view
)发送请求到服务器,在服务器中请求被Controller
接收,Controller
调用相应的Model
层处理请求,处理完毕将结果返回到Controller
,Controller
再根据请求处理的结果找到相应的View
视图,渲染数据后最终响应给浏览器
SpringMVC
是Spring
的一个后续产品,是Spring
的一个子项目。SpringMVC 是 Spring 为表述层开发提供的一整套完备的解决方案,在表述层框架历经Strust
、WebWork
、Strust2
等诸多产品的历代更迭之后,目前业界普遍选择了 SpringMVC 作为 Java EE 项目表述层开发的首选方案。SpringMVC 具有以下显著特点:
- Spring 家族原生产品,与
IOC
容器等基础设施无缝对接- 基于原生的
Servlet
,通过功能强大的前端控制器DispatcherServlet
,对请求和响应进行统一处理- 内部组件化程度高,可插拔式组件即插即用,想要什么功能配置相应组件即可
- 性能卓著,尤其适合现代大型、超大型互联网项目要求
2. 第一个 SpringMVC 程序 HelloWorld
- 新建 maven 工程,给普通的 maven 工程添加 web 模块(添加
web.xml
,指定上下文路径)- 修改 maven 工程的打包方式为
war
包并引入 springmvc 相关依赖
<!-- 1.修改 maven 工程打包方式为 war 包并引入 springmvc 相关依赖 -->
<packaging>war</packaging>
<dependencies>
<!-- 1.1. SpringMVC -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.1</version>
</dependency>
<!-- 1.2. 日志 -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
<!-- 1.3. ServletAPI -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!-- 1.4. Spring5 和 Thymeleaf 整合包 -->
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring5</artifactId>
<version>3.0.12.RELEASE</version>
</dependency>
</dependencies>
- 在 web.xml 中注册前端控制器
DispatcherServlet
,提前前端控制器的初始化时间到服务器启动时(注:默认配置方式下 SpringMVC 的配置文件默认位于WEB-INF
目录下,默认名称为<servlet-name>-servlet.xml
)
<!-- 配置前端控制器,对浏览器发送的请求统一进行处理 -->
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- SpringMVC 配置文件路径 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:mvc.xml</param-value>
</init-param>
<!-- 将前端控制器初始化时间提前到服务器启动时 -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<!-- / 不能匹配 .jsp 请求路径的请求(避免在访问jsp页面时,该请求被 DispatcherServlet 处理,从而找不到相应的页面),
/* 能够匹配所有请求,例如在使用过滤器时,若需要对所有请求进行过滤,就需要使用 /* 的写法 -->
<url-pattern>/</url-pattern >
</servlet-mapping>
- 在
Resources
目录下新建 SpringMVC 的配置文件(需与第四步init-parame
中配置的文件名相同)。在 SpringMVC 的配置文件中开启组件扫描,并配置Thymeleaf
视图解析器
<!-- 开启组件扫描 -->
<context:component-scan base-package="com.bear.mvc.controller"/>
<!-- 配置 Thymeleaf 视图解析器 -->
<bean id="viewResolver" class="org.thymeleaf.spring5.view.ThymeleafViewResolver">
<property name="order" value="1"/>
<property name="characterEncoding" value="UTF-8"/>
<property name="templateEngine">
<bean class="org.thymeleaf.spring5.SpringTemplateEngine">
<property name="templateResolver">
<bean class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver">
<!-- 视图前缀 -->
<property name="prefix" value="/WEB-INF/pages/"/>
<!-- 视图后缀 -->
<property name="suffix" value=".html"/>
<property name="templateMode" value="HTML5"/>
<property name="characterEncoding" value="UTF-8"/>
</bean>
</property>
</bean>
</property>
</bean>
- 创建请求控制器
Controller
,同时创建控制器方法处理不同的请求
/**
* @author Spring-_-Bear
* @datetime 2022/4/9 20:52
*/
@Controller
public class HelloController
/**
* @RequestMapping注解:处理请求和控制器方法之间的映射关系
* @RequestMapping注解的 value 属性可以通过请求地址匹配请求,/ 表示的当前工程的上下文路径:localhost:8080/project/
*/
@RequestMapping("/")
public String toIndex()
return "hello";
- 创建前端页面,根据第 5 步配置的
Thymeleaf
视图解析器中的路径,在对应目录下创建对应的视图页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hello World</title>
</head>
<body>
<h1>Hello World</h1>
</body>
</html>
3. SpringMVC 的请求响应流程小结
- 浏览器发送请求,若请求地址符合前端控制器的
url-pattern
,该请求就会被前端控制器DispatcherServlet
处理- 前端控制器会读取
SpringMVC
的核心配置文件,通过扫描组件找到控制器,将请求地址和控制器中@RequestMapping
注解的value
属性值进行匹配- 若匹配成功,该注解所标识的控制器方法需要返回一个字符串类型的视图名称,该视图名称会被视图解析器解析
- 视图解析器加上前缀和后缀组成视图的路径,通过
Thymeleaf
对视图进行渲染,最终转发到视图所对应页面/
被浏览器解析地址为http://localhost:8080/
/
被服务器解析为http://localhost:8080/project/
(重定向情况特殊:重定向是将新的访问地址发送给浏览器解析,所以重定向时/
对应的地址为http://localhost:8080/
)- 在前端页面中可使用
thymeleaf
动态获取当前工程的上下文路径
<!DOCTYPE html>
<!-- 需要引入 thymeleaf 的 th 名称空间 -->
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>首页</title>
</head>
<body>
<!-- 使用 @ 的形式可动态获取当前工程的上下文路径 -->
<a th:href="@/hello">Go to hello world</a><br/>
</body>
</html>
二、请求映射
4. @RequestMapping 注解的位置
@RequestMapping
标识一个类:设置映射请求的请求路径的初始信息@RequestMapping
标识一个方法:设置映射请求请求路径的具体信息
@Controller
@RequestMapping("/test")
public class RequestMappingController
// 此时前端具体请求路径为:/test/testRequestMapping
@RequestMapping("/testRequestMapping")
public String testRequestMapping()
return "success";
5. @RequestMapping 的 value、method 属性
@RequestMapping
注解的value
属性通过请求的请求地址匹配请求映射(value 属性必不可少)。value
属性是一个String
类型的数组,表示该控制器方法可以响应多个对应的请求地址
@RequestMapping(value = "/testRequestMapping", "/test")
public String testRequestMapping()
return "success";
@RequestMapping
注解的method
属性是通过请求的请求方式来匹配请求映射。method 属性是一个RequestMethod
类型的数组,表示该请求映射能够匹配多种请求方式的请求(不配置 method 属性的时表示当前控制器方法可以匹配所有请求方式的请求)- 若当前请求的请求地址满足请求映射的
value
属性,但是请求方式不满足method
属性,则浏览器报错405:Request method 'POST' not supported
@RequestMapping(value = "/testRequestMapping", "/test", method = RequestMethod.GET, RequestMethod.POST)
public String testRequestMapping()
return "success";
<a th:href="@/test">get request</a><br>
<form th:action="@/testRequestMapping" method="post">
<input type="submit">
</form>
6. @RequestMapping 的 method 的派生注解
常用的请求方式有 get,post,put,delete,但目前浏览器只支持 get 和 post,若在 form 表单提交时,为 method 设置了其他请求方式的字符串(put 或 delete),则按照默认的请求方式 get 进行处理。若要发送 put 和 delete 请求,则需要通过 spring 提供的过滤器
HiddenHttpMethodFilter
进行处理,在RESTful
部分会讲到
@GetMapping
:处理get
请求的映射@PostMapping
:处理post
请求的映射@PutMapping
:处理put
请求的映射@DeleteMapping
:处理delete
请求的映射
7. @RequestMapping 的 params、headers 属性
@RequestMapping
注解的params
属性是一个字符串类型的数组,可以通过四种表达式设置请求参数和请求映射的匹配关系(headers
的使用方法一致)
- “
param
”:请求必须携带 param 参数- “
!param
”:请求不能携带 param 参数- “
param=value
”:请求必须携带 param 参数且 param=value- “
param!=value
”:请求必须携带 param 参数且 param!=value
@RequestMapping(
value = "/testParamsAndHeaders",
params = "username=bear", "password=bear",
headers = "Connection=keep-alive", "Host=localhost:8080"
)
public String testParamsAndHeaders()
return "success";
<a th:href="@/testParamsAndHeaders(useranme='bear',password='bear')">1. testParamsAndHeaders</a>
- 若当前请求满足
@RequestMapping
注解的value
和method
属性,但是不满足params
属性,此时页面报错400
- 若当前请求满足
@RequestMapping
注解的value
和method
属性,但是不满足headers
属性,此时页面显示404
8. @RequestMapping 支持 Ant 风格的路径
?
:表示任意的单个字符*
:表示任意的 0 个或多个字符**
:表示任意的零到多层目录(在使用 ** 时,只能使用/**/xxx
的方式,**
前后不能添加内容)
// 1. ? 匹配任意单个字符
@RequestMapping("/?testAnt")
// 2. * 零到多个字符
@RequestMapping("/*testAnt")
// 3. ** 零到多层目录
@RequestMapping("/**/testAnt")
<!-- 1. 任意单个字符 -->
<a th:href="@/0testAnt">1. testAnt -> ?</a>
<!-- 2. 零到多个字符 -->
<a th:href="@/gsfgrtestAnt">2. testAnt -> *</a>
<!-- 3. 零到多层目录 -->
<a th:href="@/123/dfa/testAnt">3. testAnt -> **</a><hr/>
9. @RequestMapping 匹配路径中的占位符
原始方式:/deleteUser?id=1 | REST 方式:/deleteUser/1 |
---|
SpringMVC 路径中的占位符常用于
RESTful
风格中,当需要在请求路径中将某些数据传输到服务器时,就可以在相应的@RequestMapping
注解的value
属性中通过占位符xxx
表示传输的数据,在控制器方法参数列表中通过@PathVariable
注解将占位符所表示的数据赋值给控制器方法的形参
/**
* 通过 占位符占据请求参数的位置
* @param username 通过 @PathVariable 注解将占位符所表示的数据赋值给控制器方法的形参
*/
@RequestMapping("/testPath/username/password")
public String testPath(@PathVariable("username") String username, @PathVariable("password") String password)
System.out.println("username:" + username);
System.out.println("password:" + password);
return "success";
<!-- 以路径方式传输数据到服务器 -->
<a th:href="@/testPath/Spring-_-Bear/springbear">测试 RequestMapping 中的占位符</a>
三、获取请求参数
10. 原生 ServletAPI 获取请求参数
@RequestMapping("/testServletApi")
public String testServletApi(HttpServletRequest request)
String username = request.getParameter("username");
String password = request.getParameter("password");
System.out.println(username + " " + password);
return "success";
<a th:href="@/testServletApi(username='Spring-_-Bear',password='bear')">测试 Servlet Api 获取请求参数</a>
11. 控制器方法形参列表获取请求参数
/**
* 当通过形参获取一个 name 对应多个 value 属性时,
* 可以用 String[] 接收,也可以直接用 String 接收,此时各 value 之间使用 , 间隔
*/
@RequestMapping("/testParam")
public String testParam(String username, String password, String[] hobby)
System.out.println(username + " " + password);
System.out.println(Arrays.toString(hobby));
return "success";
12. @RequestParam 获取请求参数
value
:指定为形参赋值的请求参数的参数名(与前端的 name 属性值对应)required
:设置是否必须传输此请求参数,默认值true
(请求未传输此参数且未设置默认值则报错400
)defaultValue
:不管required
属性值为true
或false
,当value
所指定的请求参数没有传输或传输的值为""
时,则使用默认值为形参赋值
/**
* 通过 @RequestParam 注解的 value 属性可映射浏览器请求请求参数名与控制器方法形参的关系,
* required 属性可指定浏览器请求参数是否必须携带此参数,为 true 且浏览器请求中未携带且未设置默认值则报错 400
*/
@RequestMapping("/testParam")
public String testParam(@RequestParam(value = "user_name", required = false, defaultValue = "bear") String username)
System.out.println(username);
return "success";
13. @RequestHeader 获取请求参数
@RequestHeader
是将请求头信息和控制器方法的形参创建映射关系- @RequestHeader 注解一共有三个属性:value、required、defaultValue,用法同 @RequestParam
14. @CookieValue 获取请求参数
@CookieValue
是将cookie
数据和控制器方法的形参创建映射关系- @CookieValue 注解一共有三个属性:value、required、defaultValue,用法同 @RequestParam
- 第一次创建
session
会话时,服务器创建Cookie
并响应给浏览器(浏览器 Cookie 信息存在于响应报文中),此后的请求Cookie
存在于请求报文中
15. POJO 对象获取请求参数
若请求参数中不存在的 POJO 对象中的字段时则对应字段值为 null
@RequestMapping("/testPojo")
public String testPojo(User user)
System.out.println(user);
return "success";
16. 编码过滤器解决乱码问题
- 使用 SpringMVC 提供的编码过滤器
CharacterEncodingFilter
需在web.xml
中进行配置。一定要配置在其他过滤器之前,否则无效(过滤器按照在 web.xml 中的定义顺序依次进行过滤)
<!--配置 springMVC 的编码过滤器-->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceRequestEncoding</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>forceResponseEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
[SSM]详解 SpringMVC 中的拦截器异常处理器与执行流程及两种配置方式
[SSM]详解 SpringMVC 种常用的视图RESTful 风格编程实现报文信息转换器的应用与 AJAX 和 JSON 的处理