Spring MVC@RequestMapping注解属性

Posted pcdd

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring MVC@RequestMapping注解属性相关的知识,希望对你有一定的参考价值。

文章目录

@RequestMapping注解一共有8个属性,常用的有value属性、method属性,其它6个属性往往容易被忽视,因此本文将逐一介绍这8个属性的作用及用法

示例代码依赖版本如下
Spring Boot:3.0.0-SNAPSHOT
Spring MVC:6.0.0-SNAPSHOT

1.源码

@Target(ElementType.TYPE, ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
@Reflective(ControllerMappingReflectiveProcessor.class)
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 ;

以下按照源码中属性的顺序介绍(value最重要,先介绍value属性)

2.value属性

@GetMapping("/value")
public String demoValue() 
    return "value";

访问 http://127.0.0.1:8181/value 即可执行方法

3.path属性

作用同value,path、value可同时使用(不推荐),但是值必须一致
反例(两者值不相同):

@GetMapping(value = "/path", path = "/path2")
public String demoPath() 
    return "path";

运行报错

Different @AliasFor mirror values for annotation [org.springframework.web.bind.annotation.GetMapping] declared on com.example.springbootssl.controller.TestController.demoPath1(); attribute ‘path’ and its alias ‘value’ are declared with values of [/path2] and [/path].

4.name属性

@GetMapping(value = "/name", name = "name属性演示")
public String demoName() 
    return "name";

相当于方法的注释,无实际作用

5.method属性

用于设置HTTP请求方法,如GET、POST、PUT、DELETE等,类型为RequestMethod枚举类数组

public enum RequestMethod 
    GET,
    HEAD,
    POST,
    PUT,
    PATCH,
    DELETE,
    OPTIONS,
    TRACE;

    private RequestMethod() 
    

示例代码

@RequestMapping(value = "/method", method = RequestMethod.GET)
public String demoMethod() 
    return "method";

该方法需要通过GET请求来调用,在Spring4.3后可以使用@GetMapping、@PostMapping之类的注解简化编码

@GetMapping("/method")
public String demoMethod() 
    return "method";

@RequestMapping替换成@GetMapping,method属性直接不用写,两者是等价的,但后者更简洁

也可以让方法同时支持多种请求、如同时支持GET和POST,这种情况就无法使用简化的注解了

@RequestMapping(value = "/method", method = RequestMethod.GET, RequestMethod.POST)
 public String demoMethod() 
     return "method";
 

6.params属性

@GetMapping(value = "/params", params = "par=foo")
public String demoParams(@RequestParam String par) 
    System.out.println("par = " + par);
    return "params";

请求参数包含指定的key和value时,才能执行请求
若访问http://127.0.0.1:8181/params?par=bar
则HTTP状态码为400,异常信息如下:

Resolved [org.springframework.web.bind.UnsatisfiedServletRequestParameterException: Parameter conditions “par=foo” not met for actual request parameters: par=bar]

若指定多个参数,则用String数组的形式

@GetMapping(value = "/params", params = "par=foo", "par2=bar")
public String demoParams(@RequestParam String par, @RequestParam String par2) 
	// ...

必须同时满足条件,即par=foo,par2=bar才执行请求

7.headers属性

和params的作用十分相似,请求头包含指定的key和value时,才能执行请求

@GetMapping(value = "/headers", headers = "X-key=foobar")
public String demoHeaders() 
    return "headers";

此时请求头必须含有X-key且值为foobar才能执行请求
使用工具手动添加header发送请求,调用成功
要注意的是,若不符合条件返回HTTP状态码是404而不是400

8.consumes属性

当请求提交的内容MIME类型和consumes指定的一致时,才执行方法,否则返回415状态码(Unsupported Media Type)

示例代码

@PostMapping(value = "/consumes", consumes = "application/json")
public Map<String, Object> demoConsumes(@RequestBody Map<String, Object> map) 
    return map;

上述代码只有提交内容为MIME类型为application/json时,才执行方法,也就是说请求头中的Content-Type是由客户端决定的,假设为application/json,但客户端实际传的是xml格式的数据,此时由于consumes属性为application/json,两者类型不统一,因此不执行方法


反例(传入数据的MIME类型和指定的不一致):

@PostMapping(value = "/consumes", consumes = "application/xml")
public Map<String, Object> demoConsumes(@RequestBody Map<String, Object> map) 
    return map;

这时body必须传xml格式的才会被处理。故意传json格式的数据,将报如下错

此时HTTP状态码为415,也就是Unsupported Media Type

正确使用:传入xml格式的数据
在此之前,需要先搞清楚Spring MVC接收xml格式数据的方法,因为大部分都是接收JSON格式的body,直接使用@RequestBody即可,而xml也是使用该注解,但需要额外引入一个依赖,让Jackson支持xml解析

<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-xml</artifactId>
</dependency>


调用成功,传入xml数据,返回json数据

8.produces属性

作用是指定响应头中Content-Type的值
简单说就是指定返回数据的MIME类型,且仅当请求头中的Accept包含该指定类型才返回(否则返回 406状态码 Not Acceptable)

因此,客户端需要什么类型的数据,通过Accept请求头就能指定,Accept为image/*,那么服务端就必须返回图片类型的数据,若Accept为 * / *,则服务端可以返回任意MIME类型的数据了。

@GetMapping(value = "/produces", produces = "text/xml")
public Map<String, Object> demoProduces() 
    Map<String, Object> map = new LinkedHashMap<>(3);
    map.put("name", "zhangsan");
    map.put("sex", "male");
    map.put("age", 18);
    return map;

不指定produces,默认返回json格式


	"name": "zhangsan",
	"sex": "male",
	"age": 18

produces 指定为 text/xml,则返回xml格式

<Map>
    <name>zhangsan</name>
    <sex>male</sex>
    <age>18</age>
</Map>

produces 并非指定什么MIME类型,就返回什么MIME类型,直接返回传入的xml格式数据,而produces = “application/pdf”,显然是不合理的,会报以下错误:

No converter for [class …] with preset Content-Type ‘null’]

以上是关于Spring MVC@RequestMapping注解属性的主要内容,如果未能解决你的问题,请参考以下文章

spring mvc requestmapping 配置多个

Spring mvc @RequestMapping

Spring MVC @RequestMapping 标头只能接受一个值?

Spring MVC @RequestMapping注解详解

Spring MVC @RequestMapping注解详解

Spring MVC @RequestMapping浅析