@RequestMapping注解与其派生注解接收参数详解

一、前言

根据 HTTP 标准,HTTP 请求可以使用多种请求方法。

HTTP1.0 定义了三种请求方法: GET, POST 和 HEAD 方法。

HTTP1.1 新增了六种请求方法:OPTIONS、PUT、PATCH、DELETE、TRACE 和 CONNECT 方法。

@RequestMapping注解与其派生注解

在Spring Boot中,@RequestMapping是非常重要的注解之一,它可以与控制器类或方法一起使用,用于映射HTTP请求到处理程序方法上。具体来说,@RequestMapping是一个通用注解,可用于映射任何类型的请求,包括GET、POST、PUT、DELETE等。

@GetMapping、@PostMapping、@PutMapping、@DeleteMapping注解都是Spring MVC中的扩展注解。它们是对@RequestMapping注解的进一步封装和简化 ,使得使用者可以更加方便地定义RESTful API。

GET : 请求从服务器获取特定资源。例如:GET /users(获取所有学生)

POST : 在服务器上创建一个新的资源。例如:POST /users(创建学生)

PUT : 更新服务器上的资源(客户端提供更新后的整个资源)。例如:PUT /users/12(更新编号为 12 的学生)

DELETE : 从服务器删除特定的资源。例如:DELETE /users/12(删除编号为 12 的学生)

1、Get请求-@GetMapping

java 复制代码
@GetMapping("users") 
等价于
@RequestMapping(value="/users",method=RequestMethod.GET)

2、Post请求-@PostMapping

java 复制代码
@PostMapping("users") 
等价于
@RequestMapping(value="/users",method=RequestMethod.POST)

3、Put请求-@PutMapping

java 复制代码
@PutMapping("/users/{userId}") 
等价于
@RequestMapping(value="/users/{userId}",method=RequestMethod.PUT)

4、Delete请求-@DeleteMapping

java 复制代码
@DeleteMapping("/users/{userId}")
等价于
@RequestMapping(value="/users/{userId}",method=RequestMethod.DELETE)

二、RequestMapping

1、源码

java 复制代码
package org.springframework.web.bind.annotation;
@Target({ElementType.METHOD, ElementType.TYPE}) 
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface RequestMapping {
  String[] value() default {}; 
  RequestMethod[] method() default {}; 
  String[] params() default {};
  String[] headers() default {};
  String[] consumes() default {};
  String[] produces() default {}; 
}

可以发现@ RequestMapping注解中可以设置映射值、映射方法、映射参数、请求头等,下面详细讲解。

2、@RequestMapping 中的参数

RequestMapping注解有六个属性,下面我们把她分成三类进行说明。

(1) value, method;

value: 指定请求的实际地址,指定的地址可以是URI Template 模式(后面将会说明);

method: 指定请求的method类型, GET、POST、PUT、DELETE等;

(2) consumes,produces;

consumes: 指定处理请求的提交内容类型(Content-Type),例如application/json, text/html;

produces: 指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回;

(3) params,headers;

params: 指定request中必须包含某些参数值是,才让该方法处理。

headers: 指定request中必须包含某些指定的header值,才能让该方法处理请求。

3、参数传递

1、传递单个参数

java 复制代码
   @RequestMapping("/m1")
    public String m1(String name){
        return "接收到的参数name:" + name;
    }

后端接收单个参数,此处是name,字符串类型,并返回字符串

前端传过来的请求中需要带上name参数,需要名称完全一样,参数前用?与路由隔开

底层逻辑:从请求的参数中,获取参数名为name的值,并给name赋值

2、传递多个参数

@RequestMapping("/m2")

public String m2(String name, Integer age){

return "接收到的参数name:" + name + " ;age:" + age;

}

后端接收多个参数,此处是name和age,字符串类型和整形,并返回字符串

前端传过来的请求中需要带上name参数和age参数,需要名称完全一样,参数前用?与路由隔开,不同的参数间用&隔开

参数发送的顺序可以任意调换

当多个参数传值时,可以不用每个参数都传值,不传值的参数默认是null(使用包装类的前提下)

此处不用age,用Integer的原因是如果使用基本类型,必须要传值,不传会报错,所以开发时,建议使用包装类

底层逻辑:从请求的多个参数中,获取参数名为name和age的值,并给对应名称的数据赋值

3、传递对象

java 复制代码
@RequestMapping("/m3")
public String m3(Person person){
    return "接收到的参数person:" + person.toString();
}

后端接收一个对象或对象中的属性,此处是Person,并返回字符串

前端传过来的请求中可以依然用传递参数的方式,参数需要是对象中的属性名,需要名称完全一样,参数前用?与路由隔开,不同的参数间用&隔开

可以看到,用传递多个参数的方式依然可以,后端会自动读取参数中对象中名称一样的属性,对于没有的属性则不理睬

底层逻辑:从请求的参数中,自动识别与对象属性名一致的参数,并给对象中对应名称的属性赋值

4、后端参数重命名

应用场景:传过来的参数名称不方便改变,但又想改变后端中自己使用的参数名称,不想用传过来的参数名称

java 复制代码
@RequestMapping("/m4")
public String m4(@RequestParam(value = "name", required = false) String username){
    return "接收到的参数name:" + username;
}

后端:此刻用了@RequestParam后,前端传过来的参数为name(value中的值),会自动赋值给username

前端:参数名需要与value中的值保持一致

注意:如果进行了重命名,就必须要使用@RequestParam注解里的名字

底层逻辑:此处只是运用了@RequestParam注解实现了参数重命名,传递参数的逻辑与前面几种方式一致

5、传递数组

java 复制代码
@RequestMapping("/m6")
public String m6(String[] arrayParam){
    return "接收到的参数arrayParam" + Arrays.toString(arrayParam) + ", 长度" + arrayParam.length;
}

后端:接收参数是数组类型,可接收前端传来的数组类型参数

前端:当我们请求中,同一个参数有多个时,浏览器会帮我们自动给封装成一个数组

注意:参数名需完全一致,且和后端数组名相同,对应的value可以不同

底层逻辑:后端正常接收数组,前端(浏览器)发送请求时,若同一个参数有多个时,会自动将其封装成一个数组,发送给后端

6、传递集合

java 复制代码
   @RequestMapping("/m7")
    public String m7(@RequestParam(required = false) List<String> listParam){
        return "接收到的参数listParam:" + listParam + ",长度:" +listParam.size();
    }

后端:接收参数类型为集合,并加上注解@RequestParam修饰,表示后端会将前端传来的参数自动解析为集合

前端:按数组的方式进行传参,当我们请求中,同一个参数有多个时,浏览器会帮我们自动给封装成一个数组

注意:传递集合和传递数组前端传递参数的方式是没有发生改变的,改变的是后端的处理方法

底层逻辑:@RequestParam表示将前端传来的参数自动解析成该注解修饰的类型(此处是集合),注解内参数意思为若前端没有传递参数,则自动将该类型赋值为null,避免空指针报错

7、传递JSON

java 复制代码
@RequestMapping("/m8")
public String m8(@RequestBody Person person){
    return "接收到的参数person:" + person.toString();
}

后端:@RequestBody注解来将请求体内容转换为一个Person对象

前端:以JSON格式来传递参数

注意:后端参数要加上@RequestBody注解进行修饰,表示自动将前端传来的参数换成需要的参数类型,传递Json数据这种传参方式被大量使用,咱数组、对象等的参数类型全部可以用JSON传递

8、获取url中的参数

java 复制代码
@RequestMapping("/m9/{userId}/{name}")
public String m9(@PathVariable Integer userId, @PathVariable String name){
    return "userId:" + userId + ",name:" + name;
}

后端:在url中用占位符占位,然后参数用@PathVariable修饰,表示从路径中取到该参数

前端:直接在url中传参,用 / 分隔

注意:可以获取一个,也可以获取多个,但是需要注意他们的顺序,请求格式必须和后端定义的url格式匹配,否则会取错数据甚至报错

9、上传图片/文件

java 复制代码
   @RequestMapping("/m10")
    public String m10(@RequestPart MultipartFile file) throws IOException {
        // 打印文件名称
        System.out.println(file.getOriginalFilename());
        // 保存本地
        file.transferTo(new File("D:/临时,后续删除/" +file.getOriginalFilename()));
        return "success";
    }

后端:用MultipartFile类型的变量接收文件,参数使用@RequestPart注解,它用于接收文件上传

前端:直接发送文件/图片即可

注意:前端发送的文件名称必须和后端接受的参数名称完全一致,不然会报错

三、@GetMapping和@PostMapping

优点:

@GetMapping

操作简单:当我们需要从服务器获取数据时,使用@GetMapping比较方便,只需要将请求参数添加到URL路径中即可。

缓存机制:由于GET请求被浏览器缓存,因此在处理一些频繁请求的场景下,可以提升Web应用程序的性能。

安全性:由于GET请求将参数暴露在URL中,因此不太适合传输敏感信息,但是也可以通过HTTPS等协议来加密传输数据。

@PostMapping

数据安全:POST请求将数据放在请求体中,相对于GET请求更为安全,适合传输敏感信息,而且POST请求的请求体大小理论上没有限制,可以传递大量数据。

幂等性:POST请求是幂等的,即多次重复提交同一个请求,实际上只会执行一次操作,这对于插入操作非常重要。

RESTful设计:POST请求通常用于创建或更新资源,使得RESTful API设计更加符合规范。

缺点:

@GetMapping

参数长度限制:虽然GET请求理论上没有请求体的大小限制,但是URL的长度有一定的限制,因此在传递大量参数或者长字符串时,可能会出现参数被截断的情况。

安全性:由于GET请求的请求参数暴露在URL中,因此容易被恶意侵入者截获并窃取数据。

@PostMapping

操作繁琐:相对于GET请求,POST请求需要将参数放在请求体中,操作相对繁琐一些。

缓存机制:POST请求无法被浏览器缓存,因此在处理一些频繁请求的场景下,可能会降低Web应用程序的性能。

接收参数

@RequestParam 注解

在处理方法入参处使用 @RequestParam 可以把请求参数传递给请求方法的形参。

@RequestParam 注解的作用

value="name" 表示参数名称。

required=true 表示如果没有传递参数,则会报 400参数异常。

以下对前台传参数的常用方式介绍@RequestParam 注解的作用:

1、GET请求方式传递参数

java 复制代码
/**
 * @RequestParam注解获取参数(GET请求方式)
 * @param paramName
 * @return
 */
@GetMapping("/testGet1")
public String testGet1(@RequestParam("paramName") String paramName){
    System.out.println("paramName:"+paramName);
    return paramName;
}

2、POST请求方式传递参数

后台代码:

java 复制代码
/**
 * @RequestParam注解获取参数(POST请求方式)
 * @param paramName
 * @return
 */
@PostMapping("/testPost1")
public String testPost1(@RequestParam("paramName") String paramName){
    System.out.println("paramName:"+paramName);
    return paramName;
}

二、@PathVariable注解

@PathVariable注解的作用就是从URL里面读取参数值,可以在@RequestMapping里面添加占位符{paramName},还可以添加正则表达式。如http://localhost:8099/XXX/XXX/XXX/param,这个传递到后台的参数值就是param。@PathVariable注解一般用于传递一个参数的情景,当然也可以通过URL传递多个参数。

1、GET请求方式传递参数

后台代码:

java 复制代码
/**
 * @PathVariable注解的作用就是从URL里面读取参数值(GET请求方式)
 * @param paramName
 * @return
 */
@GetMapping("/testGet2/{paramName}")
public String testGet2(@PathVariable String paramName){
    System.out.println("paramName:"+paramName);
    return paramName;
}

2、POST请求方式传递参数

后台代码:

java 复制代码
/**
 * @PathVariable注解的作用就是从URL里面读取参数值(POST请求方式)
 * @param paramName
 * @return
 */
@PostMapping("/testPost2/{paramName}")
public String testPost2(@PathVariable String paramName){
    System.out.println("paramName:"+paramName);
    return paramName;
}

3、URL传递多个参数

后台代码:

java 复制代码
/**
 * @PathVariable注解的作用就是从URL里面读取参数值(GET请求方式)
 *
 * @PathVariable注解一般用于只传递一个参数的场景,当然也可以传递多个参数。
 *
 * @param param1  占位符{}添加了正则表达式,限定5位数值,如果传递过来的参数不合要求则不会执行方法的代码。
 * @param param2
 * @return
 */
@GetMapping("/testGet2_1/{param1:[0-9]{5}}/{param2}")
public String testGet2_1(@PathVariable String param1,@PathVariable String param2){
    System.out.println("param1:"+param1);
    System.out.println("param2:"+param2);
    return param1+","+param2;
}

四、SpringMVC的自动匹配

1、GET请求方式传递参数

后台代码:

java 复制代码
/**
 * springMVC的自动匹配参数(GET请求方式)
 *
 * 形参paramName会自动匹配请求中key为paramName的参数值。
 *
 * 可以接收AJAX封装的请求参数
 *
 * @param paramName
 */
@GetMapping("/testGet3")
public String testGet3(String paramName,String paramName1, Model model){
    System.out.println("paramName:"+paramName);
    System.out.println("paramName1:"+paramName1);
    model.addAttribute("paramName",paramName);
    return paramName;
}

2、POST请求方式传递参数

后台代码:

java 复制代码
/**
 * springMVC的自动匹配参数(POST请求方式)
 *
 * 形参paramName会自动匹配请求中key为paramName的参数值。
 *
 * 可以接收AJAX封装的请求参数
 *
 * @param paramName
 */
@PostMapping("/testPost3")
public String testPost3(String paramName,String paramName1, Model model){
    System.out.println("paramName:"+paramName);
    System.out.println("paramName1:"+paramName1);
    model.addAttribute("paramName",paramName);
    return paramName;

五、SpringMVC的自动装箱(实体类接收参数)

实体类定义如下:

java 复制代码
@Data
@Accessors(chain = true)
public class ParamsEntity {
 
    String param1;
    String param2;
 
}

1、GET请求方式传递参数

后台代码:

java 复制代码
/**
 * SpringMVC的自动装箱(GET请求方式)
 *
 * SpringMVC会把请求参数装箱到实体类的属性当中,属性名称就是参数名称
 *
 * @param paramsEntity
 * @return
 */
@GetMapping("/testGet4")
public String testGet4(ParamsEntity paramsEntity){
    System.out.println("params:"+paramsEntity.toString());
    return paramsEntity.toString();
}

2、POST请求方式传递参数

后台代码:

java 复制代码
/**
 * SpringMVC的自动装箱(POST请求方式)
 *
 * SpringMVC会把请求参数装箱到实体类的属性当中,属性名称就是参数名称
 *
 * @param paramsEntity
 * @return
 */
@PostMapping("/testPost4")
public String testPost4(ParamsEntity paramsEntity){
    System.out.println("params:"+paramsEntity.toString());
    return paramsEntity.toString();
}
相关推荐
XMYX-04 小时前
Spring Boot + Prometheus 实现应用监控(基于 Actuator 和 Micrometer)
spring boot·后端·prometheus
@yanyu6665 小时前
springboot实现查询学生
java·spring boot·后端
酷爱码6 小时前
Spring Boot项目中JSON解析库的深度解析与应用实践
spring boot·后端·json
java干货7 小时前
虚拟线程与消息队列:Spring Boot 3.5 中异步架构的演进与选择
spring boot·后端·架构
武昌库里写JAVA10 小时前
iview Switch Tabs TabPane 使用提示Maximum call stack size exceeded堆栈溢出
java·开发语言·spring boot·学习·课程设计
小白杨树树10 小时前
【WebSocket】SpringBoot项目中使用WebSocket
spring boot·websocket·网络协议
clk660716 小时前
Spring Boot
java·spring boot·后端
爱敲代码的TOM17 小时前
基于JWT+SpringSecurity整合一个单点认证授权机制
spring boot