Lecture04-请求-实验03-接收前端发送的数据

文章目录

    [toc]

    单词词性音标含义
    Parametern./pəˈræmɪtə(r)/参数(指方法参数或请求参数,Spring MVC中用于接收请求数据,如@RequestParam绑定的请求参数)
    requiredadj./rɪˈkwaɪəd/必需的(参数属性,如@RequestParam(required = true)表示该参数为必传,缺失则报错)
    multiadj./ˈmʌlti/多个的(指多值参数,如接收多个相同名称的请求参数,通常映射为数组或集合)
    Path Variable-/pɑːθ ˈveəriəbl/路径变量(Spring MVC中@PathVariable注解,用于绑定URL路径中的占位符到方法参数,如/user/{id}中的id)
    Entityn./ˈentəti/实体(指业务实体对象,通常对应数据库表结构,如@Entity标识JPA实体类;也指请求/响应中的数据载体)

    Lecture04-请求-实验03-接收前端发送的数据

    总体来说,前端给后端发送数据,有很多种形式:

    【1】请求参数

    userName=tom2025&password=123456&userNick=tomPig

    【2】路径变量

    • 实际请求路径举例:/user/info/2345
    • 声明路径变量:/user/info/{userId}

    【3】请求体整个是一个 JSON

    {"stuId":25, "stuName":"tom}

    image-20250729153055399

    一、使用@RequestParam注解

    @RequestParam("请求参数名")

    request.getParameter("请求参数名")

    request.getParameterValues("请求参数名")

    1、一名一值

    ①请求路径

    /param/one/name/one/value?userName=tom
    

    ②@RequestParam注解

    [1]最基本的用法

    @ResponseBody
    @RequestMapping("/param/one/name/one/value")
    public String oneNameOneValue(
            // 使用@RequestParam注解标记handler方法的形参
            // SpringMVC 会将获取到的请求参数从形参位置给我们传进来
            @RequestParam("userName") String userName
    ) {
        
        System.out.println("获取到请求参数:" + userName);
        
        return "ok";
    }
    

    [2]@RequestParam注解省略的情况

    @ResponseBody
    @RequestMapping("/param/one/name/one/value")
    public String oneNameOneValue(
            // 当请求参数名和形参名一致,可以省略@RequestParam("userName")注解
            // 但是,省略后代码可读性下降而且将来在SpringCloud中不能省略,所以建议还是不要省略
            String userName
    ) {
        
        System.out.println("★获取到请求参数:" + userName);
        
        return "ok";
    }
    

    [3]必须的参数没有提供

    ./images

    页面信息说明:

    • 响应状态码:400(在 SpringMVC 环境下,400通常和数据注入相关)
    • 说明信息:必需的 String 请求参数 'userName' 不存在

    原因可以参考 @RequestParam 注解的 required 属性:默认值为true,表示请求参数默认必须提供

    	/**
    	 * Whether the parameter is required.
    	 * <p>Defaults to {@code true}, leading to an exception being thrown
    	 * if the parameter is missing in the request. Switch this to
    	 * {@code false} if you prefer a {@code null} value if the parameter is
    	 * not present in the request.
    	 * <p>Alternatively, provide a {@link #defaultValue}, which implicitly
    	 * sets this flag to {@code false}.
    	 */
    	boolean required() default true;
    

    [4]关闭请求参数必需

    required 属性设置为 false 表示这个请求参数可有可无:

    @RequestParam(value = "userName", required = false)
    

    [5]给请求参数设置默认值

    使用 defaultValue 属性给请求参数设置默认值:

    @RequestParam(value = "userName", required = false, defaultValue = "missing")
    

    此时 required 属性可以继续保持默认值:

    @RequestParam(value = "userName", defaultValue = "missing")
    

    2、一名多值

    ①表单

    <form action="/param/one/name/multi/value" method="post">
        请选择你最喜欢的球队:
        <input type="checkbox" name="team" value="Brazil"/>巴西
        <input type="checkbox" name="team" value="German"/>德国
        <input type="checkbox" name="team" value="French"/>法国
        <input type="checkbox" name="team" value="Holland"/>荷兰
        <input type="checkbox" name="team" value="Italian"/>意大利
        <input type="checkbox" name="team" value="China"/>中国
        <br/>
        <input type="submit" value="保存"/>
    </form>
    

    ②handler方法

    @ResponseBody
    @RequestMapping("/param/one/name/multi/value")
    public String oneNameMultiValue(
        
            // 在服务器端 handler 方法中,使用一个能够存储多个数据的容器就能接收一个名字对应的多个值请求参数
            @RequestParam("team") List<String> teamList
            ) {
        
        for (String team : teamList) {
            System.out.println("team = " + team);
        }
        
        return "ok";
    }
    

    二、使用实体类对象

    ①PostMan


    ②实体类

    要求:请求参数名必须和实体类对象的属性名一致

    实体类对象属性名:getXxx()、setXxx()方法定义的

    实体类对象如何定义属性名:

    • getUserName()方法名去掉get
    • UserName
    • 剩下的部分首字母小写:userName
    • 这个属性名和成员变量名可以不同
    public class Employee {
        
        private Integer empId;
        private String empName;
        private int empAge;
        private double empSalary;
        ……
    

    ③handler方法

    @ResponseBody
    @RequestMapping("/param/form/to/entity")
    public String formToEntity(
        
            // SpringMVC 会自动调用实体类中的 setXxx() 注入请求参数
            Employee employee) {
        
        System.out.println(employee.toString());
        
        return "ok";
    }
    

    三、JSON请求体数据

    0、JSON数据格式

    JSON 最开始的时候,是 JavaScript 中定义对象的一种格式,后来大家发现这种格式表达数据的效率非常高,所以在各个领域中都广泛使用。

    JSON 格式的语法:

    • 两边符号:{}、[]
    • JSON 对象:{}
      • {属性名: 属性值, 属性名: 属性值, 属性名: 属性值, ...属性名: 属性值}
      • {stuId:66, stuName:"justin", stuSalary:25454}
    • JSON 数组:[]
      • [数组值, 数组值, 数组值, 数组值, ... 数组值,]
      • ["aaa", "bbb", "ccc"]
    • 类型:
      • 属性名:固定就是字符串类型,不管加不加引号
      • 值(属性值或数组值):
        • 基本数据类型
        • 引用类型:
          • JSON 对象
          • JSON 数组

    1、前端发送数据代码举例

    const clickHandler04 = async () => {
      let student = {stuId:66, stuName:"justin", stuSalary:25454};
      let {data} = await axiosInstance.post("/api/Servlet03ReceiveJson", student);
      content.value = data.data;
    }
    

    2、开发者工具中的显示

    image-20250528151805902


    3、实体类

    image-20250528152403453

    public class Student {
    
        private Integer stuId;
        private String stuName;
        private Double stuSalary;
    

    4、@RequestBody注解接收

    @ResponseBody
    @RequestMapping("/demo03/save/student/json")
    public String test04(
            // 实体类对象前加 @RequestBody 对应请求体的 JSON 数据
            // 实体类对象属性和 JSON 格式中的属性一致
            @RequestBody Student student) {
        return "ok " + student;
    }
    

    5、测试

    SpringMVC框架会自动把JSON转换为实体类对象

    image-20250528152447242


    6、把Student改成级联对象

    public class Student {
    
        private Integer stuId;
        private String stuName;
        private Double stuSalary;
        
        private School school;
    
        private List<Subject> subjectList;
    

    public class School {
    
        private String schoolName;
        private Integer schoolAge;
    

    public class Subject {
    
        private Integer subjectId;
        private String subjectName;
    

    前端发送的JSON数据:

    {
              "stuId": 5,
              "stuName": "aaa",
              "stuSalary": 5555.55,
              "school": {
                        "schoolName": "atguigu",
                        "schoolAge": "13"
              },
              "subjectList": [
                        {
                                  "subjectId": 3,
                                  "subjectName": "Java"
                        },
                        {
                                  "subjectId": 5,
                                  "subjectName": "MySQL"
                        }
              ]
    }
    

    后端打印效果:

    image-20250528153538164


    四、路径变量

    1、概念

    把数据作为路径的一部分,发送给后端

    前端使用路径的形式发送数据:

    /book/tom/88

    /book/jerry/99

    /book/bob/66

    后端先给路径变量命名

    @RequestMapping("/book/{author}/{price}")

    后端使用 @PathVariable 来接收路径变量传过来的值:

    @PathVariable("author") String author,

    @PathVariable("price") Double price


    2、用法

        // /subject/java
        // /subject/php
        // /subject/MySQL
        @RequestMapping("/subject/{lecture}")
        public String testPathVariable(@PathVariable("lecture") String lecture) {
            return "Path Variable:" + lecture;
        }
    
        // 1、路径中可以包含多个路径变量
        // 2、使用 IDEA 自动创建 @PathVariable 代码时,默认都是 String 类型,需要其它类型就自己修改一下
        // 3、{变量名}如果和接收路径变量的形参名一致时,@PathVariable 注解中可以省略名称
        @RequestMapping("/book/{bookName}/{author}/{price}")
        public String testPathVariableMulti(
                @PathVariable String author,
                @PathVariable String bookName,
                @PathVariable Double price) {
            return "bookName = " + bookName + " author = " + author + " price = " + price;
        }
    

    end