2023年11月28日发(作者:)

@RequestMapping注解最详细解析

⽂章⽬录

⼆、@RequestMapping注解最详细解析

2.1 @RequestMapping简介

作⽤:将请求和处理请求的控制器⽅法关联起来,建⽴映射关系。

位置:

1、标识类:设置映射请求的请求路径的初试信息

2、表⽰⽅法:设置映射请求的请求路径的具体信息

来⼀个标识类的代码实例吧:

先随便写个html⽂件,⽐如我写了⼀个叫

DOCTYPE html>

<html lang="en" th="">

<head>

<meta charset="UTF-8">

<title>Demotitle>

head>

<body>

<div>Demo1div>

body>

html>

然后再写⼀个Controller类:

package ;

import Controller;

import RequestMapping;

@Controller

@RequestMapping("/demo")

public class DemoController {

@RequestMapping("/demo1")

public String toDemo(){

return "demo";

}

}

DOCTYPE html>

<html lang="en" th="">

<head>

<meta charset="UTF-8">

<title>⾸页title>

head>

<body>

<h1>HelloWorldh1>

<a href="@{/other}">访问其他页⾯a>

<a href="@{/demo/demo1}">访问Demo页⾯a>

body>

html>

重新部署服务器并打开:

点击访问Demo页⾯,会跳转到以下页⾯

返回上⼀页,我们按F12,也可以看到:

他的超链接指向的是/demo/demo1

那加了这个有啥好处呢?最浅显易懂的好处⾃然是可以在不同的前缀下有相同的servlet啦。⽐如,我们有两个都想叫index的Servlet,此

时,我们不能将两个index都写成index,否则会报错。这个时候,我们如果⼀个是user下的index,⼀个是client下的index那不就解决问

题了吗。

Controller的代码如下:

package ;

import Controller;

import RequestMapping;

@Controller

@RequestMapping("/client")

public class ClientController {

@RequestMapping("/index")

public String toIndex(){

return "clientIndex";

}

}

package ;

import Controller;

import RequestMapping;

@Controller

@RequestMapping("/user")

public class UserController {

@RequestMapping("/index")

public String toIndex(){

return "userIndex";

}

}

如果我们把两个类名上⾯的@RequestMapping("/user")和@RequestMapping("/client")删掉,重启服务器会报错:(因为他发现有不

⽌⼀个叫index的servlet)

2.2 @RequestMapping的各个属性

2.2.1 value属性

前⾯,我们使⽤@RequestMapping注解都是直接在他的括号中加servlet的名称。

这⾥解释⼀下,默认只写⼀个参数的话,就是给value赋值。

也就是

@RequestMapping("/hello")

等价于

@RequestMapping(value = “/hello”)

注意:value属性是⼀个字符串类型的数组,表⽰请求映射能够匹配多个请求地址所对应的请求。

假如现在有代码:

@RequestMapping(value = {"/other", "/other2", "/other3"})

public String toOther(){

return "other";

那么访问other、other2、other3这三个servlet都可以导向other页⾯。

2.2.2 method属性

method属性通过请求的请求⽅式(get或post)匹配请求映射。他也是⼀个数组,但是是RequestMethod类的数组,表⽰请求映射能够

匹配多种请求⽅式的请求。

注意:直接打开⽹页的请求⽅式是GET。

当你设置了method属性之后,如果当前请求的请求地址满⾜请求映射的value属性,但是请求⽅式不满⾜method属性,则浏览器会报错

405(Request method ‘POST’ not support)

如果不设置method属性,那么⽆论是GET还是POST都可以打开我们的servlet。

所以,我们现在给我们的代码改为:

package ;

import Controller;

import RequestMapping;

import RequestMethod;

@Controller

public class HelloController {

/*POST*/

添加请求⽅式必须为请求

@RequestMapping(value = "/",method = RequestMethod.POST)

public String toIndex(){

/*,/WEB-INF/templates/.html*/

返回视图名称刚才配置⽂件会⾃⼰给他加前缀和后缀

return "index";

}

@RequestMapping(value = {"/other", "other2", "other3"})

public String toOther(){

return "other";

}

}

重启服务器,会发现,被拦住了

知识点:

1、对于处理指定请求⽅式的控制器⽅法,SpringMVC中提供了@RequestMapping的派⽣注解:

处理get请求的映射 —> @GetMapping

处理post请求的映射 —> @PostMapping

处理put请求的映射 —> @PutMapping

处理delete请求的映射 —> @DeleteMapping

2、常⽤的请求⽅式有get、post、put、delete

但是⽬前浏览器只⽀持get和post,若在form表单提交的时候,为method设置了其他请求⽅式(put或delete),则默认按照get的请求⽅

式处理。

若要发送put和delete请求,则需要通过spring提供的过滤器HiddenHttpMethodFilter(后边会有专门的博客讲解)。

2.2.3 params属性(了解)

params属性通过请求的请求参数匹配请求映射。params属性也是⼀个字符串类型的数组,可以通过以下四种表达式设置请求参数和请求

映射的匹配关系:

1、“param”:表⽰要求请求映射所匹配的请求必须携带param请求参数

2、“!param”:表⽰要求请求映射所匹配的请求不能携带param请求参数

3、“param=value”:表⽰要求请求映射所匹配的请求必须携带param请求参数且param=value

4、“param!=value”:表⽰要求请求映射所匹配的请求必须携带param请求参数且param!=value

废话不多说,代码来⼀波:

先修改类中的toOther⽅法头上 的注释如下。

@RequestMapping(

value = {"/other", "other2", "other3"},

method = {RequestMethod.GET, RequestMethod.POST},

params = {"username=Keeling","password!=123456"}

)

public String toOther(){

return "other";

}

然后重启服务器:

此时点击访问其他页⾯已经⽆法成功访问了,因为他没有username和password参数。

这个时候要想访问就得把username和password给他(记住username 必须是 Keeling,password 必须不是 123456)

如果password=123456,则

2.2.4 headers属性(了解)

headers属性通过请求的请求头信息匹配请求映射。他也是⼀个字符串类型的数组,可以通过以下四种表达式设置请求头信息和请求映射的

匹配关系:

1、“header”:表⽰请求映射所匹配的请求必须携带header请求头信息

2、“!header”:表⽰请求映射所匹配的请求必须携带header请求头信息

3、“header=value”:表⽰请求映射所匹配的请求必须携带header请求头信息,且请求头信息header = value

4、“header!=value”:表⽰请求映射所匹配的请求必须携带header请求头信息,且请求头信息header != value

注意:若当前请求满⾜value和method属性,但是不满⾜headers属性,此时页⾯显⽰404错误(资源未找到)。

代码招来

@RequestMapping(

value = {"/other", "other2", "other3"},

method = {RequestMethod.GET, RequestMethod.POST},

params = {"username=Keeling","password!=123456"},

headers = {"Connection=keep-alive"}

)

public String toOther(){

return "other";

}

重启服务器后,我们再次进⼊other页⾯成功

如果,我们把代码改为:

@RequestMapping(

value = {"/other", "other2", "other3"},

method = {RequestMethod.GET, RequestMethod.POST},

params = {"username=Keeling","password!=123456"},

headers = {"Connection=keep"}

)

public String toOther(){

return "other";

}

重启服务器,再次打开other页⾯就是这番景象了:

2.3 SpringMVC⽀持ant风格的路径

ant风格的路径是什么意思,你可以理解为是⼀种模糊的路径。

简单说就是:

使⽤ant风格,那么

表⽰任意的单个字符

* 表⽰任意的0个或多个字符

** 表⽰任意的⼀层或多层⽬录

注意:在使⽤**时, 只能使⽤/**/xxx 的⽅式

直接来⼀波代码:

@RequestMapping("h?h/*")

public String toDemo(){

return "demo";

}

重启⼀下服务器:

此时输⼊hbh/成功跳转(这个/是必须要的)

这种乱输⼊的也可以(但是前⾯h和h之间只能有⼀个字符)

为了证明?真的啥字符都⾏,我特地⽤了中⽂的感叹号,看下图

再来⼀段这个代码:(注意:两个*的)

@RequestMapping("**/hello")

public String toDemo(){

return "demo";

}

重启服务器:

直接⽤hello⾏

乱打再加hello也⾏

注意:两个*的前后不可以乱加东西,不然就不是任意⽬录了。⽐如/a**b,就是两个单独的*的意思,跟⼀个*的效果⼀样。

SpringMVC路径中的占位符常⽤于restful风格中,当请求路径中将某些数据通过路径的⽅式传输到服务器中,就可以再对于的

@RequestMapping注解的value属性中通过占位符 {xxx} 表⽰传输的数据,在通过@PathVariable注解,将占位符所表⽰的数据赋值给控

制器⽅法的形参。

讲⼏句⼈话吧,分⼏个步骤讲

1、⾸先是在@RequestMapping中⽤ {what} 占位

2、然后在⽅法的参数中⽤ 来拿这个参数。

@PathVariable("what") 什么类型 变量名

看不太懂我的所谓的“⼈话”的话,结合以下代码⼀看便知,就是这么神奇。

@RequestMapping("/demo/{username}/{password}")

public String toPath(@PathVariable("username") String username,

@PathVariable("password") String password){

System.out.println("username = "+username);

System.out.println("password = "+password);

return "demo";

}

重启服务器输⼊⽹址:

命令框显⽰如下:

如果不写密码,那么会报错

字符串类型太常见,太好⽤了,我们改⼀下:

@RequestMapping("/demo/{username}/{password}")

public String toPath(@PathVariable("username") String username,

@PathVariable("password") Integer password){

System.out.println("username = "+username);

System.out.println("password = "+password);

return "demo";

}

此时密码输⼊123(纯数字)可以成功访问