概述
@RequestMapping用于映射url到控制器类或一个特定的处理程序方法。可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。该注解共有8个属性。
@Target({ElementType.METHOD, ElementType.TYPE})
@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 {};
}
- name:指定映射的名称
- path:别名为path。指定请求的路径映射,指定的地址可以是uri模板。
- value:别名为value。使用path更加形象,在方法层面,在主要的映射在类型级别表示相对路径(例如,“edit.do”)的支持。路径映射的URI可能包含占位符(例如“/$ {}连接”)。
- method:指定请求谓词的类型如GET, POST, HEAD, OPTIONS, PUT, PATCH, DELETE, TRACE. 收窄请求范围。
- params:映射请求的参数,收窄请求范围。
- headers:映射请求头部,收窄请求范围。
- consumes:指定处理请求的提交内容类型(Content-Type),例如application/json, text/html,收窄请求范围 。
- produces:指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回。
注:Spring Framework 4.2引入了一流的支持声明和查找注释属性的别名。@AliasFor注解可用于声明一双别名属性,来给注解的属性起别名,让使用注解时,更加的容易理解(比如给value属性起别名, 更容易让人理解)。
从上面的源码可以发现除了name,基本都是数组类型,在设置时我们可以指定单个值,如@RequestMapping(value=“/foo”);也可以同时指定多个值如:@RequestMapping(value={“/foo”,“/bar”})。
1、name属性指定名称
为当前映射指定一个名称,不常用,一般不会指定。
2、path属性指定路径
@AliasFor("path")
String[] value() default {};
@AliasFor("value")
String[] path() default {};
path和values互为别名。
3、value 属性指定映射路径或URL模板
指定请求的实际地址,指定的地址可以是URL模板,正则表达式或路径占位,该属性与path互为别名关系,@RequestMapping(“/foo”)} 与 @RequestMapping(path=“/foo”)相同。该属性是使用最频繁,最重要的一个属性,如果只指定该属性时可以把value略去。
3.1、指定具体路径字符
3.1.1、只注解方法
@Controller
public class FooBarController {
@RequestMapping("/action1")
public String action1(){
return "foo/index";
}
}
访问路径:http://localhost:8080/action1
3.1.2、同时注解类与方法
@Controller
@RequestMapping("/foobar")
public class FooBarController {
@RequestMapping("/action1")
public String action1(){
return "foo/index";
}
}
访问路径:http://localhost:8080/foobar/action1
3.1.3、注解在方法上的value为空值
注解在方法上时,如果value为空则表示该方法为类下默认的Action。
@Controller
@RequestMapping("/foobar")
public class FooBarController {
@RequestMapping("/action1")
public String action1(Model model){
//在模型中添加属性message值为action1,渲染页面时使用
model.addAttribute("message", "action1");
return "foo/index";
}
@RequestMapping
public String action2(Model model){
//在模型中添加属性message值为action2,渲染页面时使用
model.addAttribute("message", "action2");
return "foo/index";
}
}
3.1.4、注解在类上的value为空值
注解在类上时,当value为空值则为默认的控制器,可以用于设置项目的起始页。
@Controller
@RequestMapping
public class FooBarController {
@RequestMapping("/action1")
public String action1(Model model){
//在模型中添加属性message值为action1,渲染页面时使用
model.addAttribute("message", "action1");
return "foo/index";
}
@RequestMapping
public String action2(Model model){
//在模型中添加属性message值为action2,渲染页面时使用
model.addAttribute("message", "action2");
return "foo/index";
}
}
访问路径:http://localhost:8080/,可用于欢迎页。
3.2、@PathVariable 路径变量占位,URI模板模式
Spring MVC可以使用@PathVariable 注释方法参数的值绑定到一个URI模板变量。
@Controller
public class ValuesController {
@RequestMapping(value = "/action3/{a}/{b}")
public String action3(Model model, @PathVariable int a,@PathVariable int b){
model.addAttribute("msg",a+b);
return "hi";
}
}
运行结果:
使用路径变量的好处:使路径变得更加简洁;获得参数更加方便,框架会自动进行类型转换。通过路径变量的类型可以约束访问参数,如果类型不一样,则访问不到action,如这里访问是的路径是/action3/1/a,则路径与方法不匹配,而不会是参数转换失败。
3.3、正则表达式模式的URI模板
@Controller
public class ValuesController {
@RequestMapping(value="/action4/{id:\\d{6}}-{name:[a-z]{3}}")
public String action4(@PathVariable int id,@PathVariable String name,Model model){
model.addAttribute("msg", "id:"+id+" name:"+name);
return "hi";
}
}
正则要求id必须为6位的数字,而name必须为3位小写字母,访问结果如下:
不符合正则表达式的访问,均会被拒绝。
3.4、矩阵变量@MatrixVariable
@MatrixVariable矩阵变量可以出现在任何路径段,每个矩阵变量用 “;” 分隔。例如:“/汽车;颜色=红;年=2012”。多个值可以是“,”分隔 “颜色=红、绿、蓝”或变量名称可以重复 “颜色=红;颜色=绿色;颜色=蓝”。
@RequestMapping(value = "/action5/{name}")
public String action5(Model model,
@PathVariable String name, //路径变量,用于获得路径中的变量name的值
@MatrixVariable String r,
@MatrixVariable(required = true) String g, //参数g是必须的
@MatrixVariable(defaultValue = "99", required = false) String b) { //参数b不是必须的,默认值是99
model.addAttribute("msg", name + " is #" + r + g + b);
return "hi";
}
默认是不允许使用矩阵变量的,设置配置文件的RequestMappingHandlerMapping的属性removeSemicolonContent为false;annotation-driven中增加属性enable-matrix-variables=“true”
<mvc:annotation-driven enable-matrix-variables="true" />
<!-- 配置映射媒体类型的策略 -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">
<property name="removeSemicolonContent" value="false" />
</bean>
访问 http://localhost:8080/action5/book;r=33;g=66 结果如下:
3.5、Ant风格路径模式
@RequestMapping注解也支持ant风格的路径模式,如/myPath/*.do,/owners/*/pets/{petId}
通配符有三种:
项目 | Value | 例子 |
---|---|---|
? | 匹配任何单字节字符 | action6/p?ttem,匹配action6/pattem、action6/pXttem,但是不匹配pttem。 |
* | 匹配0或者任意数量字符 | action6/*,匹配action6路径下所有文件。 |
** | 匹配0或者任何数量目录 | /**/example,匹配/foo/example、/example等;/**/*.jsp 匹配任何目录下.jsp文件。 |
@RequestMapping(value = "/action6/*.do")
public String action6(Model model){
model.addAttribute("msg","Ant风格路径模式");
return "hi";
}
访问 http://localhost:8080/action6/1.do 结果如下:
3.6、@RequestMapping 来处理多个 URI
你可以将多个请求映射到一个方法上去,只需要添加一个带有请求路径值列表的 @RequestMapping 注解。
@RequestMapping(value = {
"",
"/page",
"page*",
"view/*",
"**/msg"
})
public String action7(Model model){
model.addAttribute("msg","multiple mapping");
return "hi";
}
如下的这些 URL 都会由 action7() 来处理:
localhost:8080/home
localhost:8080/home/
localhost:8080/home/page
localhost:8080/home/pageabc
localhost:8080/home/view/
localhost:8080/home/view/view
4、method属性指定谓词类型
method用于约束请求的谓词类型,可以收窄请求范围。指定请求谓词的类型如GET, POST, HEAD, OPTIONS, PUT, PATCH, DELETE, TRACE。
@RequestMapping(value = "/action8",method={RequestMethod.POST, RequestMethod.DELETE})
public String action8(Model model) {
model.addAttribute("msg", "请求谓词只能是POST与DELETE");
return "hi";
}
当我们从浏览器的URL栏中直接请求时为一个GET请求,则结果是405。
我们使用postman,设置请求方式是POST:
Spring MVC 的 @RequestMapping 注解默认是 HTTP GET 类型的。如果,对于不同的请求类型,需要编写不同的逻辑,就需要自己编写映射:
@RestController
@RequestMapping("/home")
public class IndexController {
@RequestMapping(method = RequestMethod.GET)
String get() {
return "Hello from get";
}
@RequestMapping(method = RequestMethod.DELETE)
String delete() {
return "Hello from delete";
}
@RequestMapping(method = RequestMethod.POST)
String post() {
return "Hello from post";
}
@RequestMapping(method = RequestMethod.PUT)
String put() {
return "Hello from put";
}
@RequestMapping(method = RequestMethod.PATCH)
String patch() {
return "Hello from patch";
}
}
5、consumes属性指定请求的Content-Type
@RequestMapping 注解的 produces 和 consumes 这两个元素来缩小请求映射类型的范围,达到处理生产和消费对象的目的。
指定处理请求的提交内容类型(Content-Type),例如application/json, text/html,收窄请求范围,如果用户发送的请求内容类型不匹配则方法不会响应请求。
@RequestMapping(value = "/action9",consumes="text/html")
public String action9(Model model) {
model.addAttribute("msg", "请求的提交内容类型(Content-Type)是text/html");
return "hi";
}
使用postman,设置Content-Type是text/html,访问正常:
使用postman,设置Content-Type是application/x-www-form-urlencoded,报错415:
6、produces属性指定响应的Content-Type,约束Accept类型
produces指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回,方法才处理客户端的请求否则会报406错误。
Accept属性一般由客户端请求报文头上送,用于规定客户端支持的返回报文文本类型。
常见类型
- text/plain:客户端只接收纯文本
- application/*:application/*类型的内容
- application/json; charset=UTF-8:客户端接收json且编码为utf-8
@RequestMapping(value = "/action10",produces="application/json; charset=UTF-8")
public String action10(Model model) {
model.addAttribute("msg", "客户端可以接收的类型是application/json; charset=UTF-8");
return "hi";
}
7、params属性指定请求中必须有特定参数与值
params映射请求的参数,收窄请求范围。可以限制客户端发送到服务器的请求参数为某些特定值或不为某些值。
@RequestMapping(value = "/action11",params={"id=215","name!=abc"})
public String action11(Model model) {
model.addAttribute("msg", "请求的参数必须包含id=215与name不等于abc");
return "hi";
}
访问 http://localhost:8080/action11?id=215&name=xyz 结果如下:
8、headers属性指定请求中必须有特定header值
headers映射请求头部,收窄请求范围。约束客户端发送的请求头部信息中必须包含某个特定的值或不包含某个值,作用范围明显大于前面几种。
@RequestMapping(value = "/action12",headers="Host=localhost:8080")
public String action12(Model model) {
model.addAttribute("msg", "请求头部信息中必须包含Host=localhost:8080");
return "hi";
}
访问 http://localhost:8080/action12?id=215&name=xyz 结果如下:
@RequestMapping 快捷方式
Spring 4.3 引入了方法级注解的变体,也被叫做 @RequestMapping 的组合注解。组合注解可以更好的表达被注解方法的语义。它们所扮演的角色就是针对 @RequestMapping 的封装,而且成了定义端点的标准方法。
例如,@GetMapping 是一个组合注解,它所扮演的是 @RequestMapping(method =RequestMethod.GET) 的一个快捷方式。
方法级别的注解变体有如下几个:
- @GetMapping
- @PostMapping
- @PutMapping
- @DeleteMapping
- @PatchMappin
如下面两个action就是基本等价的:
@RequestMapping(value = "/action3",method = RequestMethod.GET)
public String action3(Model model){
model.addAttribute("msg","action3 get请求");
return "hi";
}
@GetMapping("/action4")
public String action4(Model model){
model.addAttribute("msg","action4 get请求");
return "hi";
}
action4的写法要简单一些