[SSM]SpringMVC 详解 @RequestMapping 注解获取请求参数和域数据共享

Posted Spring-_-Bear

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[SSM]SpringMVC 详解 @RequestMapping 注解获取请求参数和域数据共享相关的知识,希望对你有一定的参考价值。

SpringMVC

一、SpringMVC 介绍及示例

1. MVC 及 SpringMVC 的简介与特点

MVC 是一种软件架构的思想,将软件按照模型、视图、控制器来划分,分为 M(model)、V(view)、C(controller

  1. M(Model):模型层,指工程中的 JavaBean,作用是处理数据。JavaBean分为两类:
    1.1 一类称为实体类 Bean:用于存储业务数据,如 Student、User 等
    1.2 一类称为业务处理 Bean:指 ServiceDao 对象,专门用于处理业务逻辑和数据访问
  2. V(View):视图层,指工程中的 htmlJSP 等页面,作用是与用户进行交互,展示数据
  3. C(Controller):控制层,指工程中的 servlet,作用是接收请求和响应浏览器

MVC 的工作流程:用户通过视图层(view)发送请求到服务器,在服务器中请求被 Controller 接收,Controller 调用相应的 Model 层处理请求,处理完毕将结果返回到ControllerController 再根据请求处理的结果找到相应的 View 视图,渲染数据后最终响应给浏览器

SpringMVCSpring 的一个后续产品,是 Spring 的一个子项目。SpringMVC 是 Spring 为表述层开发提供的一整套完备的解决方案,在表述层框架历经 StrustWebWorkStrust2 等诸多产品的历代更迭之后,目前业界普遍选择了 SpringMVC 作为 Java EE 项目表述层开发的首选方案。SpringMVC 具有以下显著特点:

  1. Spring 家族原生产品,与 IOC 容器等基础设施无缝对接
  2. 基于原生的 Servlet,通过功能强大的前端控制器 DispatcherServlet,对请求和响应进行统一处理
  3. 内部组件化程度高,可插拔式组件即插即用,想要什么功能配置相应组件即可
  4. 性能卓著,尤其适合现代大型、超大型互联网项目要求

2. 第一个 SpringMVC 程序 HelloWorld

  1. 新建 maven 工程,给普通的 maven 工程添加 web 模块(添加 web.xml,指定上下文路径)
  2. 修改 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>
  1. 在 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>
  1. 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>
  1. 创建请求控制器 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";
    

  1. 创建前端页面,根据第 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 的请求响应流程小结

  1. 浏览器发送请求,若请求地址符合前端控制器的 url-pattern,该请求就会被前端控制器 DispatcherServlet 处理
  2. 前端控制器会读取 SpringMVC 的核心配置文件,通过扫描组件找到控制器,将请求地址和控制器中 @RequestMapping 注解的 value 属性值进行匹配
  3. 若匹配成功,该注解所标识的控制器方法需要返回一个字符串类型的视图名称,该视图名称会被视图解析器解析
  4. 视图解析器加上前缀和后缀组成视图的路径,通过 Thymeleaf 对视图进行渲染,最终转发到视图所对应页面
  5. / 被浏览器解析地址为 http://localhost:8080/
  6. / 被服务器解析为 http://localhost:8080/project/(重定向情况特殊:重定向是将新的访问地址发送给浏览器解析,所以重定向时 / 对应的地址为 http://localhost:8080/
  7. 在前端页面中可使用 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 注解的位置

  1. @RequestMapping 标识一个类:设置映射请求的请求路径的初始信息
  2. @RequestMapping 标识一个方法:设置映射请求请求路径的具体信息
@Controller
@RequestMapping("/test")
public class RequestMappingController 
	// 此时前端具体请求路径为:/test/testRequestMapping
    @RequestMapping("/testRequestMapping")
    public String testRequestMapping()
        return "success";
    

5. @RequestMapping 的 value、method 属性

  1. @RequestMapping 注解的 value 属性通过请求的请求地址匹配请求映射(value 属性必不可少)。value 属性是一个 String 类型的数组,表示该控制器方法可以响应多个对应的请求地址
@RequestMapping(value = "/testRequestMapping", "/test")
public String testRequestMapping()
    return "success";

  1. @RequestMapping 注解的 method 属性是通过请求的请求方式来匹配请求映射。method 属性是一个 RequestMethod 类型的数组,表示该请求映射能够匹配多种请求方式的请求(不配置 method 属性的时表示当前控制器方法可以匹配所有请求方式的请求)
  2. 若当前请求的请求地址满足请求映射的 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 部分会讲到

  1. @GetMapping:处理 get 请求的映射
  2. @PostMapping:处理 post 请求的映射
  3. @PutMapping:处理 put 请求的映射
  4. @DeleteMapping:处理 delete 请求的映射

7. @RequestMapping 的 params、headers 属性

@RequestMapping 注解的 params 属性是一个字符串类型的数组,可以通过四种表达式设置请求参数和请求映射的匹配关系(headers 的使用方法一致)

  1. param”:请求必须携带 param 参数
  2. !param”:请求不能携带 param 参数
  3. param=value”:请求必须携带 param 参数且 param=value
  4. 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>
  1. 若当前请求满足 @RequestMapping注解的 valuemethod 属性,但是不满足 params 属性,此时页面报错 400
  2. 若当前请求满足 @RequestMapping 注解的 valuemethod 属性,但是不满足 headers 属性,此时页面显示 404

8. @RequestMapping 支持 Ant 风格的路径

  1. :表示任意的单个字符
  2. *:表示任意的 0 个或多个字符
  3. **:表示任意的零到多层目录(在使用 ** 时,只能使用 /**/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=1REST 方式:/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 获取请求参数

  1. value:指定为形参赋值的请求参数的参数名(与前端的 name 属性值对应)
  2. required:设置是否必须传输此请求参数,默认值 true(请求未传输此参数且未设置默认值则报错 400
  3. defaultValue:不管 required 属性值为 truefalse,当 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 获取请求参数

  1. @RequestHeader 是将请求头信息和控制器方法的形参创建映射关系
  2. @RequestHeader 注解一共有三个属性:value、required、defaultValue,用法同 @RequestParam

14. @CookieValue 获取请求参数

  1. @CookieValue 是将 cookie 数据和控制器方法的形参创建映射关系
  2. @CookieValue 注解一共有三个属性:value、required、defaultValue,用法同 @RequestParam
  3. 第一次创建 session 会话时,服务器创建 Cookie 并响应给浏览器(浏览器 Cookie 信息存在于响应报文中),此后的请求 Cookie 存在于请求报文中

15. POJO 对象获取请求参数

若请求参数中不存在的 POJO 对象中的字段时则对应字段值为 null

@RequestMapping("/testPojo")
public String testPojo(User user) 
    System.out.println(user);
    return "success";

16. 编码过滤器解决乱码问题

  1. 使用 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 的处理

SSM三大框架整合配置详解

详解intellij idea搭建SSM框架(spring+maven+mybatis+mysql+junit)(上)

SSM自学教程

如何搭建SSH框架,myeclipse搭建SSH框架详解