SpringMVC 请求参数接收详解|单个参数、多参数、对象参数、@RequestParam参数重命名

目录

前言

一、项目准备

[1.1 Person实体类](#1.1 Person实体类)

[1.2 RequestController控制器](#1.2 RequestController控制器)

[二、接收单个参数 r1()](#二、接收单个参数 r1())

[三、基本类型与包装类型大坑 r2()](#三、基本类型与包装类型大坑 r2())

[Boolean参数 r3()](#Boolean参数 r3())

[四、接收多个参数 r4()](#四、接收多个参数 r4())

[五、使用Java对象(Person)接收参数 r5()](#五、使用Java对象(Person)接收参数 r5())

[六、@RequestParam 参数重命名 r6()](#六、@RequestParam 参数重命名 r6())

场景

@RequestParam注解源码关键属性

@RequestParam小结

七、常见报错汇总

八、总结

拓展阅读PDF知识点回顾


前言

SpringMVC是基于Servlet API构建的Web框架,在SpringBoot项目中勾选Spring Web依赖,底层就是SpringMVC框架。 Web开发中最核心的环节:浏览器/Postman发送请求,后端接收请求参数,执行业务逻辑,返回响应结果

本文结合课堂实战代码,讲解SpringMVC接收url查询参数的几种常见方式:

  1. 接收单个普通参数
  2. 基本类型 vs 包装类型踩坑
  3. 接收多个参数
  4. 使用实体类(Pojo)接收参数
  5. @RequestParam参数重命名、设置非必传参数

测试工具:Postman或者浏览器地址栏直接拼接参数测试


一、项目准备

创建SpringBoot项目,勾选Spring Web依赖。 两个核心类:Person.java实体类、RequestController.java控制器。

1.1 Person实体类

java 复制代码
package com.bit.spingmvcdemo.RequestController;

public class Person {
    private String name;
    private Integer gender;
    private int age;
    private String email;

    public Person() {
    }

    public Person(String name, Integer gender, int age) {
        this.name = name;
        this.gender = gender;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Integer getGender() {
        return gender;
    }

    public void setGender(Integer gender) {
        this.gender = gender;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", gender=" + gender +
                ", email='" + email + '\'' +
                '}';
    }
}

1.2 RequestController控制器

java 复制代码
package com.bit.spingmvcdemo.RequestController;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/request")
public class RequestController {
    // 1.接收单个字符串参数
    @RequestMapping("/r1")
    public String r1(String s1){
        return "接受到参数:" + s1;
    }

    // 2.接收包装类型参数
    @RequestMapping("/r2")
    public String r2(Integer age){
        if (age==null){
            return "参数不能为null";
        }
        return "接受到参数:" + age;
    }

    // 3.布尔类型参数
    @RequestMapping("/r3")
    public String r3(Boolean flag){
        return "接受到参数:" + flag;
    }

    //4.接收多个参数
    @RequestMapping("/r4")
    public String r4(String name, Integer age){
        return String.format("接受到参数: 姓名[%s], age[%d]", name, age);
    }

    //5.对象接收参数
    @RequestMapping("/r5")
    public String r5(Person person){
        return "接受到参数: "+ person;
    }

    //6.@RequestParam参数重命名,设置非必传
    @RequestMapping("/r6")
    public String r6(@RequestParam(value = "sa", required = false) String name){
        return "接受到参数: "+ name;
    }
}

知识点:@RestController = @Controller + @ResponseBody,该类所有方法返回值直接作为http响应数据,不会去找视图页面。


二、接收单个参数 r1()

代码:

java 复制代码
@RequestMapping("/r1")
public String r1(String s1){
    return "接受到参数:" + s1;
}

访问地址: http://127.0.0.1:8080/request/r1?s1=helloworld

  • 规则:请求参数key和方法形参名字保持一致,SpringMVC自动赋值
  • 如果不传s1参数,s1值为null,不会报错。

三、基本类型与包装类型大坑 r2()

java 复制代码
@RequestMapping("/r2")
public String r2(Integer age){
    if (age==null){
        return "参数不能为null";
    }
    return "接受到参数:" + age;
}

访问:http://127.0.0.1:8080/request/r2?age=18

⚠️重点踩坑:

  1. 如果形参写int age(基本数据类型),请求不传age,直接报500内部服务器错误。基本类型不能接收null。
  2. 如果形参写Integer age(包装类),不传参数时age = null,程序不会崩溃。 企业开发建议:接收前端参数,尽量使用包装类型(Integer、Boolean),不要使用int、boolean基本类型

Boolean参数 r3()

java 复制代码
@RequestMapping("/r3")
public String r3(Boolean flag){
    return "接受到参数:" + flag;
}

传参:?flag=true / ?flag=false,不传参得到null


四、接收多个参数 r4()

java 复制代码
@RequestMapping("/r4")
public String r4(String name, Integer age){
    return String.format("接受到参数: 姓名[%s], age[%d]", name, age);
}

访问: http://127.0.0.1:8080/request/r4?name=zhangsan&age=20

规则:

  1. url使用&分割多个参数。
  2. 参数顺序无关,只匹配参数名称?age=20&name=zhangsan同样可以拿到数据。
  3. 某个参数不传,对应变量为null(包装类)。

五、使用Java对象(Person)接收参数 r5()

java 复制代码
@RequestMapping("/r5")
public String r5(Person person){
    return "接受到参数: "+ person;
}

访问地址: http://127.0.0.1:8080/request/r5?name=张三&gender=1&age=22&email=test@qq.com

核心规则:

  1. 请求参数的key,必须和Person实体类的成员变量名完全一致
  2. SpringMVC底层调用setter方法给属性赋值,实体类必须有无参构造方法。
  3. 某个参数不传:引用类型赋值null;基本类型int age,会赋默认值0。

注意:这里是接收url查询参数、form表单参数,不是接收JSON!接收JSON需要加@RequestBody注解


六、@RequestParam 参数重命名 r6()

场景

前端传的参数名字和后端方法参数名字不一致,例如前端参数名叫sa,后端变量叫name,此时使用@RequestParam注解做映射。

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

访问:http://127.0.0.1:8080/request/r6?sa=testdata

@RequestParam注解源码关键属性

java 复制代码
public @interface RequestParam {
    String value() default ""; //前端参数名称
    boolean required() default true; //是否必传,默认true,不传直接400报错
    String defaultValue() default ""; //默认值
}
  1. required = true(默认):参数必须传递,否则返回400 Bad Request
  2. required = false:参数非必传,不传时变量等于null

坑点:如果不加required=false,访问/request/r6不带sa参数,直接400错误。

@RequestParam小结

写法 参数是否必传 作用
@RequestParam("sa") String name ✅必传 将前端sa映射到后端name
@RequestParam(value="sa",required=false) String name ❌非必传 映射,允许不传参
String name ❌非必传 参数名必须完全一致

七、常见报错汇总

  1. 500 内部错误:Optionat int parameter 'age'is present but cannot be translated into a null value

    原因:使用int基本类型接收,前端不传参数。解决:改为包装类型Integer age

  2. 400 Bad Request MissingServletRequestParameterException

    原因:@RequestParam默认required=true,但是请求没有携带对应参数。 解决:设置required=false或者前端必须传递该参数。

  3. 对象接收参数属性全部null

    排查:①参数名和实体类属性名不一致;②实体类没有无参构造;③没有setter方法。


八、总结

  1. 接收简单参数:方法形参名与请求参数名保持一致,自动注入。
  2. 参数类型优先包装类Integer/Boolean,避开基本类型null赋值异常。
  3. 参数多的时候直接封装POJO实体类接收,减少方法形参。
  4. 前后端参数名不一致,用@RequestParam(value="xxx")做映射;required=false设置非必传。
  5. @RequestParam默认必传,不传直接400,开发很容易踩坑。
相关推荐
__zRainy__1 小时前
Node系列 · ORM:Sequelize 简介
数据库·后端·node.js
AskHarries2 小时前
OpenClaw 如何查看历史对话和响应时间?
后端
n8n2 小时前
Spring Boot 3.2+ 新特性、Spring AI 核心架构与 API Key 安全管理技术文档
后端
古法安卓2 小时前
Android-epoll原理详解
android·java·android studio
fireworks992 小时前
接口鉴权(401与403)
java·后端
wear工程师2 小时前
线程池里的异常去哪了?execute 和 submit 不是一回事
java
n8n2 小时前
Java 21 虚拟线程(Virtual Threads)
后端
孔明click332 小时前
别人绕过我的网关直接调用资源服务怎么办?使用 Sa-Token 解决:网关转发鉴权、RPC调用鉴权
java·sa-token·springboot·权限·权限认证
吴声子夜歌2 小时前
Java面试——设计模式(一)
java·设计模式·面试