SpringMVC中@RequestMapping注解的用法(全面)
@RequestMapping是SpringMVC中的核心注解,SpringMVC中的映射请求就是使用改注解来完成的,这个注解用来指定控制器可以处理哪些请求,其所做的工作相当于在web.xml中配置了servlet完成映射。下面我们来具体了解一下@RequestMapping的用法
@RequestMapping的作用范围
通过查看RequestMapping注解类的源码可以看到,在其@Target注解中,有两个属性值,说明@RequestMapping注解既可以添加在类上,也可以添加在方法上。
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface RequestMapping {
String name() default "";
@AliasFor("path")
String[] value() default {};
@AliasFor("value")
String[] path() default {};
RequestMethod[] method() default {};
String[] params() default {};
String[] headers() default {};
String[] consumes() default {};
String[] produces() default {};
}
当添加在类上时,会将某个特定的请求映射到某个控制器上,例如localhost:8080/user就会定位到HelloController上,但是作用在类上的注解需要和方法上的路径组合才可一个可访问路径。例如下面的localhost:8080/user/testRequestMapping就可以成功跳转到success页面。当类上没有加@RequestMapping注解,那么访问路径直接为localhost:8080/testRequestMapping
@Controller
@RequestMapping(path = "/user")
public class HelloController {
/**
* RequestMapping
* @return
*/
@RequestMapping(path = "/testRequestMapping")
public String testRequestMapping(String username){
System.out.println("测试RequestMapping...");
return "success";
}
}
@RequestMapping的初级理解
上一段@RequestMapping注解源码中可以看到,path和value互为别名,path和value作为@RequestMapping的属性表达的都是映射地址,当只有这一个属性时,可以省略属性名称而直接赋值,即@RequestMapping("/user")和@RequestMapping(value="/user")以及@RequestMapping(path="/user")三者是同义表达。
且源码中显示,path和value的值为数组,说明可以指定多个值,当指定多个值时,表示将多个请求映射在同一个方法上,例如下面:
@Controller
public class HelloController {
@RequestMapping(
{"/testRequestMapping",
"/try*",
"/*",
"/requestMapping"})
public String testRequestMapping(String username){
System.out.println("测试RequestMapping...");
return "success";
}
}
以下这些请求路径均会映射到testRequestMapping方法上,最终跳转到success页面。
http://localhost:8080/tryRequestMapping
http://localhost:8080/try
http://localhost:8080/132
http://localhost:8080/testRequestMapping
http://localhost:8080/requestMapping
带参数的@RequestMapping
@Request Mapping的params属性
该属性表示请求的参数,当请求的路径中包含params中指定的某些参数值时,该请求才会被处理,否则不予处理,例如下面
@Controller
@RequestMapping(path = "/user")
public class HelloController {
@RequestMapping(value = "/hello",params = {"username=maize"})
public String sayHello(){
System.out.println("Hello SpringMVC");
return "success";
}
}
下面路径中均包含了"username=maize",下列的请求均会被该方法处理。
http://localhost:8080/user/hello?username=maize
http://localhost:8080/user/hello?username=maize&password=12
http://localhost:8080/user/hello?password=12&username=maize
但是需要注意的是,http://localhost:8080/user/hello?username=maize12中虽然有"username=maize",但是其参数为username=maize12而非username=maize,该方法不会处理这个请求。
在@RequestMapping源码中params也是一个数组,说明可以赋值多个参数,当赋值多个参数值时,请求路径中将这些参数以&连接,至于参数的顺序可自由排序
@Controller
@RequestMapping(path = "/user")
public class HelloController {
@RequestMapping(value = "/hello",
params = {
"username=maize",
"password=321",
"age=18"})
public String sayHello(){
System.out.println("Hello SpringMVC");
return "success";
}
}
http://localhost:8080/user/hello?password=321&age=18&username=maize
http://localhost:8080/user/hello?password=321&username=maize&age=18等等符合条件的请求均会被处理
@RequestMapping和 @RequestParam
这两个注解的配合使用可以将请求的参数同处理方法的参数绑定在一起,@RequestParam 的name属性和value属性互为别名,指定参数的名称,只有参数名称这一参数时,属性名称可以省略不写。
@Controller
@RequestMapping(path = "/user")
public class HelloController {
@RequestMapping("/testRequestParam")
public String testRequestParam(@RequestParam(name="username") String username){
System.out.println("username:"+username);
return "success";
}
}
当以http://localhost:8080/user/testRequestParam?username=maize请求时,控制台会打印出传入的参数:
@RequestParam的required属性,定义了当前参数是否一定需要,当required值为true时,说明请求的路径中一定要带有相关参数,否则不会处理,required值为false时,请求路径中没有相关参数也会处理。
当@RequestParam未带任何参数时,会自动匹配路径中的参数名称和方法的参数名称,名称一致时会匹配成功并赋值。
@RequestMapping和@PathVariable
在Spring3.0以后,增加了带占位符的URL,可以使用@PathVariable注解将占位符中的参数绑定到方法的参数中,使用{}表示占位符
@Controller
@RequestMapping(path = "/user")
public class HelloController {
@RequestMapping("/testPathVariable/{name}")
public String testPathVariable(@PathVariable(name = "name") String name){
System.out.println("name:"+name);
return "success";
}
}
在上面的URL中,{name}表示占位符,使用@PathVariable(name = “name”)和方法参数name绑定,请求路径的填充就会自动赋值给参数name。例如:
http://localhost:8080/user/testPathVariable/maize该请求路径会被方法处理,且name会被赋值为maize。
@RequestMapping和请求头
@RequestMapping的headers属性用于指定请求的请求头,请求头包含许多有关客户端环境和请求正文的信息,例如浏览器支持的语言、请求的服务器地址、客户端的操作系统等,当请求头匹配成功时,才会响应。(请求头可以在前端页面下按F12,查看network)
下列表示接受请求头为Accept的请求
@Controller
@RequestMapping(path = "/user")
public class HelloController {
@RequestMapping(path = "/testHeader",headers = "Accept")
public String testHeader(){
System.out.println("请求成功");
return "success";
}
}
@RequestMapping和请求方式
Http规范定义了多种请求资源的方式,一般分为四种:GET,POST,DELETE,PUT,这四种分别对应查询,增加,删除和更新。为了规范编码,@RequestMapping的method参数定义了请求资源的方式,对应上述四种的取值分别为:RequestMethod.GET,RequestMethod.POST,RequestMethod.DELETE,RequestMethod.PUT。
以method指定了请求资源的方式后,方法只会对对应的请求方式下的请求路径做出处理
HelloController.java
@Controller
@RequestMapping(path = "/user")
public class HelloController {
@RequestMapping(value = "/test",method = RequestMethod.GET)
public String testGet(){
System.out.println("请求方式为GET");
return "success";
}
@RequestMapping(value = "/test",method = RequestMethod.POST)
public String testPost(){
System.out.println("请求方式为POST");
return "success";
}
}
前端from表单
<form action="user/test" method="post">
<input type="submit" value="提交"/>
</form>
在点击提交按钮后,控制台打印的结果如下:
上面两个方法的请求路径一致,均为/user/test,但由于form表单中指定请求方式为POST,于是执行的是POST对应的方法
目前在SpringBoot中已经封装了Restful风格的请求注解,如@GetMapping是@RequestMapping和method=RequestMethod.GET的组合,@PostMapping、@DeleteMapping、@PutMapping类似
@RequestMapping和提交的内容类型
@RequestMapping的consumes属性指定处理请求的提交内容类型,在HTTP协议Header中的ContentType表明当前发送的数据是什么格式,例如application/json, text/html,consumes指定了值,方法仅处理请求头中Content-Type为相应类型的请求,例如:
@RequestMapping(consumes="application/json")
那么方法只会对请求头中Content-Type为"application/json"类型的请求做出处理
@RequestMapping和返回值类型
中的ContentType表明当前发送的数据是什么格式,例如application/json, text/html,consumes指定了值,方法仅处理请求头中Content-Type为相应类型的请求,例如:
@RequestMapping(consumes="application/json")
那么方法只会对请求头中Content-Type为"application/json"类型的请求做出处理
@RequestMapping和返回值类型
@Request Mapping中的produces指定返回值类型,上一小点中讲解的consumes 是用来限制请求头中ContentType。那么produces就是用来限制请求头中的Accept,Accept用来向服务器表明客户端认识什么样的数据格式,返回的数据格式也是相应的类型才会被解析。取值和consumes属性一样