Spring MVC 请求参数绑定与常用注解

第一部分:@RequestMapping 注解深度解析

1.1 四个核心属性

⭐ 老师强调 :@RequestMapping 的作用是建立请求 URL 与处理方法的映射关系。它有四个常用属性:path、value、method、params。

属性 说明 备注
path 指定请求路径 任何时候都不能省略
value 同 path 当注解只有一个属性且为 value 时,可省略不写
method 限制请求方式 如 RequestMethod.GET、POST、DELETE、PUT
params 限制请求参数 如 params = "username",要求必须携带该参数

⭐ 老师强调:

  • value 的省略规则 :只有单一属性时才能省,一旦加上 method 等属性,value 必须显式写出。
  • path 永远不能省。
  • method 管"怎么发请求"(如超链接默认是 GET,若接口限定为 POST 则会报错)。
  • params 管"带什么参数",可以写多个(如数组形式)。

1.2 HTTP 状态码回顾

⭐ 老师强调:排查请求错误时,必须分清状态码含义。

状态码 含义 原因分析
200 请求成功 仅代表访问到接口,不代表业务逻辑正确
404 找不到资源 路径写错
405 请求方式错误 路径匹配上了,但 method 不匹配(如超链接发 GET,接口限 POST)
500 服务器内部错误 后端代码抛出异常(逻辑错)
400 请求参数异常 参数缺失(如 params = "username" 但没带)

⭐ 老师强调 :GET 请求携带参数是在 URL 上用问号拼接,如 ?username=xxx,绝非 POST。

第二部分:请求参数绑定

2.1 绑定机制与数据类型

⭐ 老师强调 :早期 Servlet 用 request.getParameter("name") 手动取参。Spring MVC 底层基于此,但通过方法参数列表直接声明,框架自动帮你绑定赋值。

绑定的核心要求 :表单提交的 name 属性 必须与 控制器方法参数名/实体类属性名 完全一致(区分大小写)。

支持的数据类型:

  1. 基本数据类型和字符串类型
  2. 实体类型(JavaBean)
  3. 集合数据类型(List、Map等)
  4. 复杂嵌套类型(实体套实体、实体套集合等)

2.2 六大绑定形式详解

1. 基本数据类型与字符串(同名接收)

复制代码
@RequestMapping("/save1.do")
public String save(String username, Integer age) {
    // 前端 form 的 name="username" 和 name="age" 自动绑定到这里
    return "suc";
}

2. 实体类(JavaBean)接收

⭐ 老师强调 :如果字段多(如10个),挨个写参数太麻烦。用实体类接收,只要 name 和实体类属性名一致,自动映射。

复制代码
public class User implements Serializable {
    private String username;
    private Integer age;
    // 有参/无参构造、get/set、toString 缺一不可
}

@RequestMapping("/save2.do")
public String save2(User user) {
    System.out.println(user);
    return "suc";
}

3. 实体类嵌套实体类(点语法接收)

前端表单必须写成 对象.属性 的形式:

复制代码
金额:<input type="text" name="address.money" />

@RequestMapping("/save3.do")
public String save3(User user) {
    System.out.println(user);
    return "suc";
}

4. 实体类嵌套集合(索引接收)

前端表单必须写成 集合[索引].属性 的形式:

复制代码
集合1:<input type="text" name="list[0].money" />
集合2:<input type="text" name="list[1].money" />

@RequestMapping("/save4.do")
public String save4(User user) {
    System.out.println(user);
    return "suc";
}

5. 参数名不一致(使用 @RequestParam 绑定)

⭐ 老师强调 :当方法形参名与前端 name 不一致时,用 @RequestParam 绑定。

复制代码
@RequestMapping("/save1.do")
public String save(@RequestParam(value = "username", required = false, defaultValue = "abc") String name) {
    // required=true 默认,不传报 400;defaultValue 不传时给默认值
    return "suc";
}

6. 使用原生 Servlet API

⭐ 老师强调:框架虽然做了简化,但依然支持原生 API。只需要在方法参数中定义,框架会自动注入。

复制代码
@RequestMapping("/save6.do")
public String save6(HttpServletRequest request, HttpServletResponse response, HttpSession session) {
    System.out.println(request.getParameter("username"));
    return "suc";
}

第三部分:中文乱码与日期格式转换

3.1 乱码的根源

⭐ 老师强调:电脑底层只认 0 和 1。字符要进电脑,先按某种编码(如 UTF-8)转成字节流,再转二进制。若用 UTF-8 编码,却用 GBK 解码,就会乱码(就像 A 密码本加密,B 密码本解密)。浏览器传值默认是 ISO-8859-1,后端默认也用这个解,就产生乱码。

3.2 解决乱码的三种方式

⭐ 老师强调:第一种侵入代码、局部生效;第二种更灵活但麻烦;第三种过滤器才是最佳实践。

方式一:手动设置请求编码(局部/全局) 在 Servlet 或 Controller 方法第一行设置:

复制代码
request.setCharacterEncoding("UTF-8");

方式二:String 重构转码(针对单一参数)

复制代码
String name = new String(request.getParameter("username").getBytes("ISO-8859-1"), "UTF-8");

方式三:配置 Spring 提供的过滤器(最佳实践) 在 web.xml 中配置,拦截所有请求,统一设置编码:

复制代码
<!-- 配置过滤器,解决中文乱码的问题 -->
<filter>
    <filter-name>characterEncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <!-- 指定字符集 -->
    <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>characterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

⭐ 老师强调 :如果配置了过滤器还是乱码,检查是否遗漏了 <init-param> 指定编码,或者 IDEA/Tomcat 自身的编码配置不对。

3.3 日期格式转换

⭐ 老师强调 :前端表单传日期默认格式是 yyyy/MM/dd(斜杠)。如果用横杠 yyyy-MM-dd,框架会默认转换失败报错。有两种解决方案:

方式一:@DateTimeFormat 注解(推荐,简单) 直接在实体类的日期属性上加注解:

复制代码
import org.springframework.format.annotation.DateTimeFormat;

public class User implements Serializable {
    // 规定前端传这个格式的日期
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date birthday;
}

方式二:自定义类型转换器(适合复杂格式)

  1. 编写转换器类,实现 Converter<S, T> 接口:

    public class StringToDate implements Converter<String, Date> {
    @Override
    public Date convert(String s) {
    if(s == null) throw new RuntimeException("请输入内容");
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    try {
    return sdf.parse(s);
    } catch (ParseException e) {
    throw new RuntimeException(e);
    }
    }
    }

  2. 在 springmvc.xml 中注册转换器:

    <mvc:annotation-driven conversion-service="conversionService" />

⭐ 老师强调 :自定义转换器后,框架遇到该类转换不走默认模式,完全接管。

第四部分:常用注解详解

4.1 @RequestParam

  • 作用:把请求中指定名称的参数赋值给控制器方法的形参(解决名不一致问题)。
  • 属性 :
    • value:请求参数的名字。
    • required:是否必须(默认 true,不传报错 400)。
    • defaultValue:默认值。

4.2 @RequestBody

  • 作用 :获取请求体内容(注意:GET 请求没有请求体,不能用)。
  • 属性 :required(默认 true)。
  • 注意 :常用于接收前端传来的 JSON 数据。

4.3 @PathVariable

  • 作用 :绑定 URL 中的占位符 。用于支持 RESTful 风格。

  • 属性 :value(URL 中占位符的名字)。

  • RESTful 风格示例:

    @RequestMapping(path = "/emp/{id}", method = RequestMethod.GET)
    public String findById(@PathVariable(value = "id") Integer id) {
    System.out.println("通过id查询员工..." + id);
    return "suc";
    }

⭐ 老师强调 :RESTful 风格(请求路径一样,根据 method 不同去执行不同后台方法)结构清晰,是行业标准。此时 web.xml 前端控制器的 url-pattern 要改为 /,否则 {id} 会被当作扩展名截断。

4.4 @RequestHeader 和 @CookieValue

  • @RequestHeader :获取请求头的值(如 Accept)。
  • @CookieValue :获取指定 Cookie 的值(如 JSESSIONID)。
相关推荐
一条泥憨鱼1 小时前
AI Agent 安全实践:从 MCP 工具调用到 Java 权限校验
java·人工智能·安全
Nebula_g1 小时前
云禾外卖补充—项目整体后端运行逻辑-对流程的更深层次理解
java·开发语言·网络·数据库·状态模式·javase
萧瑟余晖1 小时前
Spring Security 6.x新特性与架构演进详解
java·spring·架构
\光辉岁月/1 小时前
1.Object类
java·面向对象·object类
鸽鸽程序猿2 小时前
【项目】【在线判题系统】公共功能
java·spring boot·maven
一只笨菜鸟2 小时前
IDEA如何让多个项目同时显示
java·ide·intellij-idea
萧瑟余晖2 小时前
Spring Security架构总览与过滤器链详解
spring·架构
G018_star sky♬2 小时前
java中的字符串常见方法
java·开发语言
.Bryce.3 小时前
你了解 Blackboard(黑板系统)吗?听说过基于黑板系统实现的智能体吗?
java·网络·gpt·php·agent·codex·黑板系统