开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第25天,点击查看活动详情
@RequestMapping 注解
1、功能
从注解名称上我们可以看到,@RequestMapping注解的作用就是将请求和处理请求的控制器方法关联起来,建立映射关系
SpringMVC 接收到指定的请求,就会来找到在映射关系中对应的控制器方法来处理这个请求
控制器中有多个方法对应同一个请求的情况
这是一种特殊情况,我们定义至少两个控制类,其中定义的控制器方法上@ReqeustMapping指定同一请求路径
@Controller
public class HelloController {
@RequestMapping("/")
public String index() {
return "index";
}
}
@Controller
public class RequestMappingController {
@RequestMapping("/")
public String index() {
return "target";
}
}
如果存在两个或多个控制器,其控制器方法的@RequestMapping一致,即多个控制器方法试图都想要处理同一个请求时,这时启动 Tomcat 时会抛出BeanCreationException异常,并指明There is already 'helloController' bean method即 helloController 中存在处理同意请求的控制器方法
但是这显然是不合理的,当一个系统方法很多,很难完全避免两个或多个同名方法的存在
@RequestMapping不仅可以在控制器方法上进行使用,也可以在控制器类上进行使用。那两种方式有什么区别呢?
@RequestMapping标识一个类:设置映射请求的请求路径的初始信息
@RequestMapping标识一个方法:设置映射请求的请求路径的具体信息
@Controller
@RequestMapping("/requestMappingController")
public class RequestMappingController {
@RequestMapping("/success")
public String success() {
return "success";
}
}
前台创建超链接,超链接跳转路径 = 控制器上@RequestMapping映射请求的初始路径 + 控制器方法上@RequestMapping映射请求的具体路径,即/requestMappingController/success
这样就可以为不同的控制器方法,在设置映射请求的请求路径时,指定不同的初始信息,从而避免控制器中有多个方法对应同一个请求的情况
指定请求方式
method属性可以用来指定可处理的请求方式。
1、常用的请求方式有 4 种:GET、POST、PUT、DELETE
- GET 用于查询数据
- POST 用于添加数据
- PUT 用于更新数据
- DELETE 用户删除数据
但是很多情况下,习惯上会让 POST 承担更多的职责,即通过 POST 进行增、删、改的操作,可以说是“一个人揽了三个人的活”
2、还有 4 种不常用的请求:HEAD、PATCH、OPTIONS、TRACE
- HEAD 获取响应的报头,检查超链接的有效性、网页是否被修改,多用于自动搜索机器人获取网页的标志信息,获取 rss 种子信息,或者传递安全认证信息等
- PATCH 用于更新数据
- OPTIONS 用于测试服务器,解决同源策略和跨域请求问题
- TRACE 用于测试或诊断
例如:
我们期望让请求的资源路径为 /test/testMethod的POST请求能够被testMethod方法处理。则可以写如下代码
@Controller
@RequestMapping("/test")
public class TestController {
@RequestMapping(value = "/testMethod",method = RequestMethod.POST)
public String testMethod(){
System.out.println("testMethod处理了请求");
return "/success.jsp";
}
}
注意:我们可以也可以运用如下注解来进行替换
- @PostMapping 等价于 @RequestMapping(method = RequestMethod.POST)
- @GetMapping 等价于 @RequestMapping(method = RequestMethod.GET)
- @PutMapping 等价于 @RequestMapping(method = RequestMethod.PUT)
- @DeleteMapping 等价于 @RequestMapping(method = RequestMethod.DELETE)
例如:
上面的需求我们可以使用下面的写法实现
@Controller
@RequestMapping("/test")
public class TestController {
@PostMapping(value = "/testMethod")
public String testMethod(){
System.out.println("testMethod处理了请求");
return "/success.jsp";
}
}
不满足 method 会怎样
若当前请求的请求地址满足请求映射的value属性,但是请求方式不满足method属性,则浏览器报错
value 属性
@RequestMapping注解的value属性有哪些用途呢?
- 请求映射:通过请求的请求地址匹配请求映射
- 匹配多个请求:是一个字符串类型的数组,表示该请求映射能够匹配多个请求地址所对应的
-
必须设置:至少通过一个请求地址匹配请求映射
匹配多个请求
查看@RequestMapping注解的源码,会发现其value属性返回值为 String 类型的数组,这也说明了之所以@RequestMapping注解的value属性可以匹配多个请求的原因。通过为value属性指定多个值的方式,就可以对个多个请求建立请求映射
指定请求参数
我们可以使用params属性来对请求参数进行一些限制。可以要求必须具有某些参数,或者是某些参数必须是某个值,或者是某些参数必须不是某个值。
例如:
我们期望让请求的资源路径为 /test/testParams的GET请求,并且请求参数中具有code参数的请求能够被testParams方法处理。则可以写如下代码
@Controller
@RequestMapping("/test")
public class TestController {
//需要多个参数的时候
// @RequestMapping(value = "/testParams",method = RequestMethod.GET,params = {"code","id"})
//只要一个参数
@RequestMapping(value = "/testParams",method = RequestMethod.GET,params = "code")
public String testParams(){
System.out.println("testParams处理了请求");
return "/success.jsp";
}
}
如果是要求不能有code这个参数可以把改成如下形式
@Controller
@RequestMapping("/test")
public class TestController {
@RequestMapping(value = "/testParams",method = RequestMethod.GET,params = "!code")
public String testParams(){
System.out.println("testParams处理了请求");
return "/success.jsp";
}
}
如果要求有code这参数,并且这参数值必须是某个值可以改成如下形式
@Controller
@RequestMapping("/test")
public class TestController {
@RequestMapping(value = "/testParams",method = RequestMethod.GET,params = "code=sgct")
public String testParams(){
System.out.println("testParams处理了请求");
return "/success.jsp";
}
}
如果要求有code这参数,并且这参数值必须不是某个值可以改成如下形式
@Controller
@RequestMapping("/test")
public class TestController {
@RequestMapping(value = "/testParams",method = RequestMethod.GET,params = "code!=sgct")
public String testParams(){
System.out.println("testParams处理了请求");
return "/success.jsp";
}
}
指定请求头
们可以使用headers属性来对请求头进行一些限制。
@RequestMapping注解的headers属性通过请求的请求头信息匹配请求映射
它是一个字符串类型的数组,可以通过四种表达式设置请求头信息和请求映射的匹配关系
header:要求请求映射所匹配的请求必须携带header请求头信息
header:要求请求映射所匹配的请求必须不能携带header请求头信息
header=value:要求请求映射所匹配的请求必须携带header请求头信息且header=value
-
header!=value:要求请求映射所匹配的请求必须携带header请求头信息且header!=value
若当前请求满足@RequestMapping注解的value和method属性,但是不满足headers属性,此时页面显示404错误,即资源未找到
例如:
我们期望让请求的资源路径为 /test/testHeaders的GET请求,并且请求头中具有deviceType的请求能够被testHeaders方法处理。则可以写如下代码
@Controller
@RequestMapping("/test")
public class TestController {
@RequestMapping(value = "/testHeaders",method = RequestMethod.GET,headers = "deviceType")
public String testHeaders(){
System.out.println("testHeaders处理了请求");
return "/success.jsp";
}
}
如果是要求不能有deviceType这个请求头可以把改成如下形式
@Controller
@RequestMapping("/test")
public class TestController {
@RequestMapping(value = "/testHeaders",method = RequestMethod.GET,headers = "!deviceType")
public String testHeaders(){
System.out.println("testHeaders处理了请求");
return "/success.jsp";
}
}
如果要求有deviceType这个请求头,并且其值必须是某个值可以改成如下形式
@Controller
@RequestMapping("/test")
public class TestController {
@RequestMapping(value = "/testHeaders",method = RequestMethod.GET,headers = "deviceType=ios")
public String testHeaders(){
System.out.println("testHeaders处理了请求");
return "/success.jsp";
}
}
如果要求有deviceType这个请求头,并且其值必须不是某个值可以改成如下形式
@Controller
@RequestMapping("/test")
public class TestController {
@RequestMapping(value = "/testHeaders",method = RequestMethod.GET,headers = "deviceType!=ios")
public String testHeaders(){
System.out.println("testHeaders处理了请求");
return "/success.jsp";
}
}
指定请求头Content-Type
我们可以使用consumes属性来对Content-Type这个请求头进行一些限制。
范例一
我们期望让请求的资源路径为 /test/testConsumes的POST请求,并且请求头中的Content-Type头必须为 multipart/from-data 的请求能够被testConsumes方法处理。则可以写如下代码
@RequestMapping(value = "/testConsumes",method = RequestMethod.POST,consumes = "multipart/from-data")
public String testConsumes(){
System.out.println("testConsumes处理了请求");
return "/success.jsp";
}
范例二
如果我们要求请求头Content-Type的值必须不能为某个multipart/from-data则可以改成如下形式:
@RequestMapping(value = "/testConsumes",method = RequestMethod.POST,consumes = "!multipart/from-data")
public String testConsumes(){
System.out.println("testConsumes处理了请求");
return "/success.jsp";
}
4.RestFul风格
RestFul是一种网络应用程序的设计风格和开发方式 。现在很多互联网企业的网络接口定义都会符合其风格。
主要规则如下:
- 每一个URI代表1种资源
- 客户端使用GET、POST、PUT、DELETE 4个表示操作方式的动词对服务端资源进行操作:GET用来获取资源,POST用来新建资源,PUT用来更新资源,DELETE用来删除资源;
- 简单参数例如id等写到url路径上 例如: /user/1 HTTP GET:获取id=1的user信息 /user/1 HTTP DELETE :删除id=1的user信息
- 复杂的参数转换成json或者xml(现在基本都是json)写到请求体中。