【SpringMVC】| 一文带你搞定SpringMVC的@RequestMapping注解

目录

环境搭建

@Request注解的功能

1. @RequestMapping注解的位置

2、@RequestMapping注解的【value】属性

3、@RequestMapping注解的【method】属性

4、@RequestMapping注解的【params】属性(了解)

5、@RequestMapping注解的【headers】属性(了解)

6、SpringMVC支持ant风格的路径

7、SpringMVC支持路径中的占位符(重点)


环境搭建

pon.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>org.example</groupId>
  <artifactId>springmvc-thymeleaf002</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>

  <name>springmvc-thymeleaf002 Maven Webapp</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <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>
    <!--springmvc依赖-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.2.5.RELEASE</version>
    </dependency>
    <!--servlet依赖-->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
      <scope>provide</scope>
    </dependency>
    <!--logback日志框架依赖-->
    <dependency>
      <groupId>ch.qos.logback</groupId>
      <artifactId>logback-classic</artifactId>
      <version>1.2.11</version>
    </dependency>
    <!--spring整合thymeleaf的依赖-->
    <dependency>
      <groupId>org.thymeleaf</groupId>
      <artifactId>thymeleaf-spring5</artifactId>
      <version>3.0.10.RELEASE</version>
    </dependency>
  </dependencies>

  <build>
    <!--指定资源文件的位置-->
    <resources>
      <resource>
        <directory>src/main/java</directory>
        <includes>
          <include>**/*.xml</include>
          <include>**/*.properties</include>
        </includes>
      </resource>
      <resource>
        <directory>src/main/resources</directory>
        <includes>
          <include>**/*.xml</include>
          <include>**/*.properties</include>
        </includes>
      </resource>
    </resources>

  </build>
</project>

在web.xml注册DispatcherServlet前端控制器

<?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框架-->
    <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>
        <!--将前端控制器DispatcherServlet的初始化时间提前到服务器启动时-->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

在springmvc.xml中配置包扫描和thymeleaf的视图解析器

<?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"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       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 http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
    <!--配置包扫描-->
    <context:component-scan base-package="com.zl.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/templates/"/>
                        <!-- 视图后缀 -->
                        <property name="suffix" value=".html"/>
                        <property name="templateMode" value="HTML5"/>
                        <property name="characterEncoding" value="UTF-8"/>
                    </bean>
                </property>
            </bean>
        </property>
    </bean>
   
</beans>

@Request注解的功能

(1)从注解名称上我们可以看到,@RequestMapping注解的作用就是将请求和处理请求的控制器方法关联起来,建立映射关系。

(2)SpringMVC 接收到指定的请求,就会来找到在映射关系中对应的控制器方法来处理这个请求。

1. @RequestMapping注解的位置

@RequestMapping标识一个:设置映射请求的请求路径的初始信息

@RequestMapping标识一个法:设置映射请求请求路径的具体信息

(1)只出现在方法上

package com.zl.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class ControllerTest {
    @RequestMapping("/")
    public String demo(){
        return "index";
    }
}

此时的访问路径就是:http://localhost:8080/springmvc/WEB-INF/templates/index.html,其中springmvc是上下文路径!

(2)出现在类上

注:表示在具体的映射路径前面又增加了一个路径,为了区分不同类的同一个请求!

例如:对于用户User可能有一个请求list;对于订单Order也可能有一个list;如果不加以区分就会报错,都是http://localhost:8080/springmvc/list,服务器就不知道到该访问哪一个。此时就可以在类前面在使用@RequestMapping注解加一层路径的名称!

package com.zl.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("/action")
public class ControllerTest {
    @RequestMapping("/")
    public String demo(){
        return "index";
    }
}

此时的访问路径就是:http://localhost:8080/springmvc/action/WEB-INF/templates/index.html,其中springmvc是上下文路径!

2、@RequestMapping注解的【value】属性

注:【value属性】是通过请求的【请求地址】来匹配请求

(1)@RequestMapping注解的value属性通过请求的请求地址匹配请求映射。

(2)@RequestMapping注解的value属性是一个字符串类型的数组表示该请求映射能够匹配多个请求地址所对应的请求。

(3)@RequestMapping注解的value属性必须设置,至少通过请求地址匹配请求映射!

注:前面就是使用了value属性,只不过只有一个值就省略了value属性的名。实际上vlaue属性是一个字符串数组,可以有多个值!

@AliasFor("path")
String[] value() default {};

需求:多个请求地址访问同一个资源!

在index.html中配置两个请求地址

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <a th:href="@{/test1}">请求方式1</a>
    <a th:href="@{/test2}">请求方式2</a>
</body>
</html>

@RequestMapping注解的value属性指定多个值

package com.zl.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;


@Controller
public class ControllerTest {
    @RequestMapping("/")
    public String demo(){
        return "index";
    }

    @RequestMapping(value = {"/test1","/test2"})
    public String toSuccess(){
        return "success";
    }
}

测试:此时无论是/test1请求还是/test2请求都能访问到success资源

3、@RequestMapping注解的【method】属性

注:【method属性】是通过请求的【请求方式】来匹配请求(不仅要满足请求的地址相同,请求的方式也要相同

(1)@RequestMapping注解的method属性通过请求的请求方式(get或post)匹配请求映射。

(2)@RequestMapping注解的method属性是一个RequestMethod类型的数组,表示该请求映射能够匹配多种请求方式的请求。

(3)若当前请求的请求地址满足请求映射的value属性,但是请求方式不满足method属性则浏览器报错405:Request method 'POST' not supported。

 RequestMethod[] method() default {};

RequestMethod实际上实际上一个枚举类型

package org.springframework.web.bind.annotation;

public enum RequestMethod {
    GET,HEAD,POST,PUT,PATCH,DELETE,OPTIONS,TRACE;
    private RequestMethod() {
    }
}

注:如果在@RequestMappring注解中没有使用method去指定请求的方式,那么无论前端发过来get还是post都可以进行匹配;因为此时不是以method顺序ing来匹配请求了!

例:前端分别使用get(默认就是get)和post发送请求

在index.html中配置两个请求地址get和post

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!--默认就是get请求方式提交-->
<a th:href="@{/test1}">get请求方式</a><br>
<!--post请求方式-->
<form th:action="@{/test2}" method="post">
    <input type="submit" value="post请求方式">
</form>
</body>
</html>

@RequestMapping注解的value属性指定多个值,并且不指定请求方式

   @RequestMapping(value = {"/test1","/test2"})
    public String toSuccess(){
        return "success";
    }

测试:此时无论是get请求发送的/test1请求还是post请求发送的/test2请求都能访问到success资源;此时实际上就不以请求方式来进行匹配了,就是单纯的通过地址进行匹配!

 例:如果此时在@RequestMapping中使用method属性设置了请求方式;此时如果地址路径匹配上了,但是请求方式没有匹配上会报405错误

@RequestMapping注解的value属性指定多个值,并且设置的请求方式为get

    @RequestMapping(value = {"/test1","/test2"},method = RequestMethod.GET)
    public String toSuccess(){
        return "success";
    }

 测试:此时对于test2发送的时候使用的是post请求,接收的时候使用get请求,会报405错误

例:如果让请求映射既支持get请求又支持post请求,怎么办?

前面已经说了method属性是一个RequestMethod类型的数组,所以我们可以把两个都写上

    @RequestMapping(value = {"/test1","/test2"},
                 method = {RequestMethod.GET,RequestMethod.POST})
    public String toSuccess(){
        return "success";
    }

注:

(1)对于处理指定请求方式的控制器方法,SpringMVC中提供了@RequestMapping的派生注解

①处理get请求的映射-->@GetMapping注解

②处理post请求的映射-->@PostMapping注解

③处理put请求的映射-->@PutMapping注解

④处理delete请求的映射-->@DeleteMapping注解

前端发送post请求

<!--发送post请求,为了测试PostMapping注解-->
<form th:action="@{/postmapping}" method="post">
    <input type="submit" value="post请求方式">
</form>

后端使用@PostMapping注解接收

注:  @PostMapping("/postmapping")就等同于@RequestMapping(value = "/postmapping",method = RequestMethod.POST)

    @PostMapping("/postmapping")
    public String testPostMapping(){
        return "success";
    }

(2)常用的请求方式有get,post,put,delete

①但是目前浏览器只支持get和post,若在form表单提交时,为method设置了其他请求方式的字符串(put或delete),则按照默认的请求方式get处理

②若要发送put和delete请求,则需要通过spring提供的过滤器HiddenHttpMethodFilter,在RESTful部分会讲到!

4、@RequestMapping注解的【params】属性(了解)

注:【params属性】是通过请求的【请求参数】来匹配请求

(1)@RequestMapping注解的params属性通过请求的请求参数匹配请求映射

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

String[] params() default {};

"param":要求请求映射所匹配的请求必须携带param请求参数

"!param":要求请求映射所匹配的请求必须不能携带param请求参数

"param=value":要求请求映射所匹配的请求必须携带param请求参数且param=value

"param!=value":要求请求映射所匹配的请求必须携带param请求参数但是param!=value

后端使用param属性

解释:以下表示前端发送的请求必须有username属性,属性值随意;必须含有password属性,属性值也必须是123。

    @RequestMapping(value = "/param",
                    params = {"username","password=123"})
    public String toParam(){
        return "success";
    }

前端请求

注:可以使用?也可以使用()的形式;但是?IDEA会出现红色的下划线,但是不影响正常使用

<!--方式一-->
<a th:href="@{/param?username='root'&password=123}">param属性的方式</a>
<!--方式二-->
<a th:href="@{/param(username='root',password=123)}">param属性的方式</a>

5、@RequestMapping注解的【headers】属性(了解)

注:【headers属性】是通过请求的【请求头信息】来匹配请求

(1)@RequestMapping注解的headers属性通过请求的请求头信息匹配请求映射;用法和param属性的使用方式是相同的。

(2)@RequestMapping注解的headers属性是一个字符串类型的数组,可以通过四种表达式设置请求头信息和请求映射的匹配关系:

"header":要求请求映射所匹配的请求必须携带header请求头信息

"!header":要求请求映射所匹配的请求必须不能携带header请求头信息

"header=value":要求请求映射所匹配的请求必须携带header请求头信息且header=value

"header!=value":要求请求映射所匹配的请求必须携带header请求头信息且header!=value

若当前请求满足@RequestMapping注解的value和method属性,但是不满足headers属性此时页面显示404错误,即资源未找到!

6、SpringMVC支持ant风格的路径

注:这种风格的请求,实际上就是支持模糊匹配!

(1)?表示任意的单个字符

后端代码

    @RequestMapping("/a?b/testAnt1")
    public String test1(){
        return "success";
    }

前端代码

①?是匹配单个字符,所以中间只能有一个字符,例如a1a,a2a等都可以!

②不能是特殊的字符,例如:问号?、斜杠/等。例如:a?a不可以,再例如aa,直接省略不写也不行。

<!--中间匹配一个字符-->
<a th:href="@{/a1b/testAnt1}">测试1</a>
<a th:href="@{/acb/testAnt1}">测试2</a>

(2)*:表示任意的0个或多个字符

后端代码

    @RequestMapping("/a*b/testAnt1")
    public String test2(){
        return "success";
    }

前端代码

<!--中间不匹配字符、匹配一个字符、匹配多个字符都可以-->
<a th:href="@{/cb/testAnt2}">测试3</a><br>
<a th:href="@{/c1b/testAnt2}">测试4</a><br>
<a th:href="@{/cccb/testAnt2}">测试5</a><br>

(3)**:表示任意的一层或多层目录;

使用两个**就可以使用【斜杠/】表示一层或多层目录;但是使用两个**有语法要求,此时**的前后都不能有东西,所以只能在斜杠后面,例如:/**。但如果前后有东西,例如:a**b,那么此时的**就真是普通的*,没有任何特殊的含义!

注意:在使用**时,只能使用/**/xxx的方式!

后端代码

    @RequestMapping("/**/testAnt3")
    public String test3(){
        return "success";
    }

前端代码

<!--任意一个路径、多层路径、省略不写都是可以的-->
<a th:href="@{/abc/testAnt3}">测试6</a><br>
<a th:href="@{/ab/c/testAnt3}">测试7</a><br>
<a th:href="@{/testAnt3}">测试8</a><br>

7、SpringMVC支持路径中的占位符(重点)

原始方式:/deleteUser?id=1

restful方式:/deleteUser/1

SpringMVC路径中的占位符常用于RESTful风格中,当请求路径中将某些数据通过路径的方式传输到服务器中,就可以在相应的@RequestMapping注解的value属性中通过占位符{xxx}表示传输的数据,在通过@PathVariable注解,将占位符所表示的数据赋值给控制器方法的形参!

注:仅限于超链接地址栏提交数据,它是一杠一值(前端传数据)一杠一大括号(后端接收数据),使用注解@PathVariable(路径变量)来解析。

前端代码:一杠一值

<a th:href="@{/testRest/jack/12}">测试路径中的占位符-->/testRest</a><br>

后端代码:一杠一大括号

    @RequestMapping("/testRest/{name}/{age}")
    public String toRest(@PathVariable String name, @PathVariable int age){
        System.out.println("name:"+name+", age:"+age);
        return "success";
    }

执行结果:成功获取到前端提交的数据

猜你喜欢

转载自blog.csdn.net/m0_61933976/article/details/130892669