• 【Spring MVC】@RequestMapping注解属性


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

    示例代码依赖版本如下
    Spring Boot:3.0.0-SNAPSHOT
    Spring MVC:6.0.0-SNAPSHOT
    server.port=8181

    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 {};
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

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

    2.value属性

    @GetMapping("/value")
    public String demoValue() {
        return "value";
    }
    
    • 1
    • 2
    • 3
    • 4

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

    @GetMapping(value = {"/foo", "/bar"})
    public String demoValue() {
        return "value";
    }
    
    • 1
    • 2
    • 3
    • 4

    访问 http://127.0.0.1:8181/foo 或 http://127.0.0.1:8181/bar 均执行该方法

    3.path属性

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

    @GetMapping(value = "/path", path = "/path2")
    public String demoPath() {
        return "path";
    }
    
    • 1
    • 2
    • 3
    • 4

    运行报错

    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";
    }
    
    • 1
    • 2
    • 3
    • 4

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

    5.method属性

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

    public enum RequestMethod {
        GET,
        HEAD,
        POST,
        PUT,
        PATCH,
        DELETE,
        OPTIONS,
        TRACE;
    
        private RequestMethod() {
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    示例代码

    @RequestMapping(value = "/method", method = RequestMethod.GET)
    public String demoMethod() {
        return "method";
    }
    
    • 1
    • 2
    • 3
    • 4

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

    @GetMapping("/method")
    public String demoMethod() {
        return "method";
    }
    
    • 1
    • 2
    • 3
    • 4

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

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

    @RequestMapping(value = "/method", method = {RequestMethod.GET, RequestMethod.POST})
     public String demoMethod() {
         return "method";
     }
    
    • 1
    • 2
    • 3
    • 4

    6.params属性

    请求参数包含指定的key和value时,才能执行请求

    @GetMapping(value = "/params", params = "par=foo")
    public String demoParams(@RequestParam String par) {
        System.out.println("par = " + par);
        return "params";
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    请求参数par的值必须为foo时才可执行该方法
    若访问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) {
    	// ...
    }
    
    • 1
    • 2
    • 3
    • 4

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

    7.headers属性

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

    @GetMapping(value = "/headers", headers = "X-key=foobar")
    public String demoHeaders() {
        return "headers";
    }
    
    • 1
    • 2
    • 3
    • 4

    此时请求头必须含有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;
    }
    
    • 1
    • 2
    • 3
    • 4

    上述代码只有提交内容为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;
    }
    
    • 1
    • 2
    • 3
    • 4

    这时body必须传xml格式的才会被处理。故意传json格式的数据,将报如下错
    在这里插入图片描述
    此时HTTP状态码为415,也就是Unsupported Media Type

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

    <dependency>
        <groupId>com.fasterxml.jackson.dataformatgroupId>
        <artifactId>jackson-dataformat-xmlartifactId>
    dependency>
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述
    调用成功,传入xml数据,返回json数据

    9.produces属性

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

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

    @GetMapping(value = "/produces", produces = "application/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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    produces为application/xml,返回xml格式的数据

    <Map>
        <name>zhangsanname>
        <sex>malesex>
        <age>18age>
    Map>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    produces为application/json,返回json格式的数据

    {
    	"name": "zhangsan",
    	"sex": "male",
    	"age": 18
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

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

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

  • 相关阅读:
    2023年亚太杯数学建模思路 - 案例:最短时间生产计划安排
    最高的牛(一般问题转化为差分)
    前端工程师都在用的 VSCode 常用插件
    C语言从入门到精通 第二章(数据的表现形式)
    在SpringBoot中使用Spring-AOP实现接口鉴权
    C#中HashMap和HashTable有什么区别
    【Python】【OpenCV】关于cv2.findContours()轮廓索引(编号)解析(RETR_TREE)
    MFC Windows 程序设计[244]之简单的偏好(附源码)
    面试官:分布式ID的生成方案有哪些?雪花算法生成的ID由哪些部分组成?
    【重拾C语言】八、表单数据组织——结构体(类型、类型别名、直接/间接访问;典例:复数、成绩单)
  • 原文地址:https://blog.csdn.net/weixin_43553153/article/details/127759191