第一部分:@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 属性 必须与 控制器方法参数名/实体类属性名 完全一致(区分大小写)。
支持的数据类型:
- 基本数据类型和字符串类型
- 实体类型(JavaBean)
- 集合数据类型(List、Map等)
- 复杂嵌套类型(实体套实体、实体套集合等)
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;
}
方式二:自定义类型转换器(适合复杂格式)
-
编写转换器类,实现
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);
}
}
} -
在
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)。