本文纲要
- 请求路径映射
@RequestMapping基本用法
类级别与方法级别路径的组合 - 普通参数传递与中文乱码处理
GET / POST发送普通参数
接收参数
乱码过滤器配置 - 五种参数类型传递
普通参数(同/不同名)
POJO对象参数
嵌套POJO参数
数组参数
集合参数 JSON数据传递
添加Jackson依赖与开启JSON转换
@RequestBody接收JSON
集合、对象、对象集合的接收- 日期类型参数处理
@DateTimeFormat指定格式 - 控制器响应
页面跳转
文本响应
JSON响应与HttpMessageConverter - 核心流程与总结
请求路径映射
1 ) 概念
在 Spring MVC 中,使用 @RequestMapping 注解将某个请求路径映射到指定的控制器方法上。当一个 HTTP 请求的 URL 与方法上注解的路径匹配时,对应的控制器方法就会被执行。
为了避免团队开发时不同模块路径冲突,通常在类上添加公共前缀,类上的路径与方法上的路径会进行拼接,形成最终的请求 URL。
2 ) 项目结构
以 springmvc_03_request_mapping 为例,关键目录结构如下:
springmvc_03_request_mapping
├── pom.xml
└── src
└── main
├── java
│ └── com
│ └── wb
│ ├── config
│ │ ├── ServletContainersInitConfig.java
│ │ └── SpringMvcConfig.java
│ └── controller
│ ├── BookController.java
│ └── UserController.java
└── webapp
└── index.jsp
3 )代码实现
pom.xml 核心依赖:
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
</dependencies>
配置类 SpringMvcConfig.java:
package com.wb.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan("com.wb.controller")
public class SpringMvcConfig {
}
ServletContainersInitConfig.java 初始化前端控制器:
package com.wb.config;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
protected Class<?>[] getServletConfigClasses() {
return new Class[]{SpringMvcConfig.class};
}
protected String[] getServletMappings() {
return new String[]{"/"};
}
protected Class<?>[] getRootConfigClasses() {
return new Class[0];
}
}
控制器示例 – 初始未加类前缀时的冲突:
// BookController.java
package com.wb.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class BookController {
@RequestMapping("/save")
@ResponseBody
public String save(){
System.out.println("book save ...");
return "{'module':'book save'}";
}
}
// UserController.java
package com.wb.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class UserController {
@RequestMapping("/save")
@ResponseBody
public String save(){
System.out.println("user save ...");
return "{'module':'user save'}";
}
@RequestMapping("/delete")
@ResponseBody
public String delete(){
System.out.println("user delete ...");
return "{'module':'user delete'}";
}
}
此时启动会报错,因为 /save 路径重复。
解决方案:通过类级别映射路径添加前缀
// UserController.java 改进版
package com.wb.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@RequestMapping("/user") // 设置当前模块前缀
public class UserController {
@RequestMapping("/save")
@ResponseBody
public String save(){
System.out.println("user save ...");
return "{'module':'user save'}";
}
@RequestMapping("/delete")
@ResponseBody
public String delete(){
System.out.println("user delete ...");
return "{'module':'user delete'}";
}
}
// BookController.java 改进版
@Controller
@RequestMapping("/book")
public class BookController {
@RequestMapping("/save")
@ResponseBody
public String save(){
System.out.println("book save ...");
return "{'module':'book save'}";
}
}
路径映射规律
- 当类上有
@RequestMapping("/user"),方法上有@RequestMapping("/save")时,最终访问路径为/user/save。 - Postman 测试:
GET http://localhost/user/saveGET http://localhost/book/save
小结
@RequestMapping可标明在类上(模块公共前缀)和方法上(具体功能路径)。- 完整路径 = 类前缀 + 方法路径。
- 作用:避免项目内路径冲突,提高可维护性。
普通参数传递与中文乱码处理
1 ) 概念
通过 URL 问号传参或表单传递普通参数(数字、字符串等),Spring MVC 可以自动将请求参数绑定到控制器方法的形参上,依据 名称相同 的原则。处理 POST 请求的中文乱码,需要配置 CharacterEncodingFilter。
2 ) 项目结构
基于 springmvc_04_request_param:
springmvc_04_request_param
├── pom.xml
└── src/main/java/com/wb
├── config
│ ├── ServletContainersInitConfig.java
│ └── SpringMvcConfig.java
└── controller
└── UserController.java
3 ) 代码说明
pom.xml 添加 Jackson 依赖,用于后续 JSON 处理:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
SpringMvcConfig.java 基础配置:
package com.wb.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan("com.wb.controller")
public class SpringMvcConfig {
}
ServletContainersInitConfig.java 中配置乱码过滤器:
package com.wb.config;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
import javax.servlet.Filter;
public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
protected Class<?>[] getRootConfigClasses() {
return new Class[0];
}
protected Class<?>[] getServletConfigClasses() {
return new Class[]{SpringMvcConfig.class};
}
protected String[] getServletMappings() {
return new String[]{"/"};
}
// 处理中文乱码
@Override
protected Filter[] getServletFilters() {
CharacterEncodingFilter filter = new CharacterEncodingFilter();
filter.setEncoding("UTF-8");
return new Filter[]{filter};
}
}
UserController.java 接收普通参数:
package com.wb.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class UserController {
// GET/POST 请求普通参数,形参与参数名一致即可自动绑定
@RequestMapping("/commonParam")
@ResponseBody
public String commonParam(String name, int age){
System.out.println("普通参数 name ==> " + name);
System.out.println("普通参数 age ==> " + age);
return "{'module':'common param'}";
}
}
Postman 测试
- GET:
http://localhost/commonParam?name=wf&age=15 - POST: 选择 Body → x-www-form-urlencoded,填入 name=wf&age=15
中文乱码处理
当 POST 表单包含中文时,需添加上述 CharacterEncodingFilter。处理后中文可以正常接收。
五种参数类型传递
Spring MVC 支持多种参数绑定方式,满足不同业务场景。
1 ) 普通参数:名称不同时使用 @RequestParam
若请求参数名为 name,但方法参数名为 userName,可用 @RequestParam 绑定:
@RequestMapping("/commonParamDifferentName")
@ResponseBody
public String commonParamDifferentName(@RequestParam("name") String userName, int age){
System.out.println("userName ==> " + userName);
System.out.println("age ==> " + age);
return "{'module':'common param different name'}";
}
访问时仍发送 name=xxx&age=yy,userName 可以接收到值。
2 ) POJO 对象参数
当请求参数与实体类属性同名时,可以直接将参数封装为对象。
// domain/User.java
package com.wb.domain;
public class User {
private String name;
private int age;
private Address address; // 后面嵌套使用
// 省略 getter/setter/toString
}
@RequestMapping("/pojoParam")
@ResponseBody
public String pojoParam(User user){
System.out.println("pojo参数 user ==> " + user);
return "{'module':'pojo param'}";
}
请求:name=wf&age=15,user 对象自动填充。
3 ) 嵌套 POJO 参数
当实体类内部包含其他对象时,使用“属性名.属性名”传递。
Address 类:
package com.wb.domain;
public class Address {
private String province;
private String city;
// getter/setter/toString
}
请求格式:name=wf&age=15&address.province=北京&address.city=北京
控制器方法同 pojoParam,无需修改,框架自动封装。
4 ) 数组参数
请求中同名参数会自动映射到数组。
@RequestMapping("/arrayParam")
@ResponseBody
public String arrayParam(String[] likes){
System.out.println("数组参数 likes ==> " + Arrays.toString(likes));
return "{'module':'array param'}";
}
请求:likes=Java&likes=Spring&likes=MyBatis
结果:数组包含三个元素。
5 ) 集合参数
直接使用 List<String> 接收会报错,因为框架默认将其视为 POJO 并尝试创建实例。需要添加 @RequestParam 注解明确为参数绑定。
@RequestMapping("/listParam")
@ResponseBody
public String listParam(@RequestParam List<String> likes){
System.out.println("集合参数 likes ==> " + likes);
return "{'module':'list param'}";
}
请求方式与数组相同。
五种参数传递总结表
| 参数类型 | 请求格式 | 形参示例 | 关键注解 |
|---|---|---|---|
| 普通参数(同名) | ?name=xx&age=yy | String name, int age | 无 |
| 普通参数(不同名) | ?name=xx | @RequestParam("name") String userName | @RequestParam |
| POJO | ?name=xx&age=yy | User user | 无 |
| 嵌套 POJO | ?address.province=北京 | User user (内部含 address) | 无 |
| 数组 | ?likes=A&likes=B | String[] likes | 无 |
| 集合 | ?likes=A&likes=B | @RequestParam List<String> likes | @RequestParam |
JSON 数据传递
1 ) 概念
当前后端分离时,主流交互格式为 JSON。Spring MVC 需要依赖 Jackson 库,并使用 @EnableWebMvc 开启自动转换,再用 @RequestBody 将 JSON 请求体绑定到对象或集合。
配置三步走
pom.xml中引入jackson-databind。- 在 Spring MVC 配置类上添加
@EnableWebMvc:
@Configuration
@ComponentScan("com.wb.controller")
@EnableWebMvc // 开启 JSON 自动转换
public class SpringMvcConfig {
}
在方法参数前加 @RequestBody。
1 ) 接收 JSON 集合(普通类型)
@RequestMapping("/listParamForJson")
@ResponseBody
public String listParamForJson(@RequestBody List<String> likes){
System.out.println("list common(json) likes ==> " + likes);
return "{'module':'list common for json param'}";
}
Postman 发送:Body → raw → JSON → ["Java","Spring","MyBatis"]
2 ) 接收 JSON POJO 对象
@RequestMapping("/pojoParamForJson")
@ResponseBody
public String pojoParamForJson(@RequestBody User user){
System.out.println("pojo(json) user ==> " + user);
return "{'module':'pojo for json param'}";
}
请求体 JSON:
{
"name":"wf",
"age":15,
"address":{
"province":"北京",
"city":"北京"
}
}
3 ) 接收 JSON 对象集合
@RequestMapping("/listPojoParamForJson")
@ResponseBody
public String listPojoParamForJson(@RequestBody List<User> list){
System.out.println("list pojo(json) list ==> " + list);
return "{'module':'list pojo for json param'}";
}
请求体:
[
{"name":"wf","age":15},
{"name":"wf2","age":12}
]
JSON 参数传递要点
@RequestBody表示从请求体中获取数据,适用于 POST/PUT 等。@EnableWebMvc配置不可少,否则 JSON 映射会失败。- 单一方法中
@RequestBody只能使用一次。
日期类型参数处理
Spring MVC 默认可解析 yyyy/MM/dd 格式的日期。对于其他格式,需用 @DateTimeFormat 指定 pattern。
@RequestMapping("/dataParam")
@ResponseBody
public String dataParam(Date date,
@DateTimeFormat(pattern="yyyy-MM-dd") Date date1,
@DateTimeFormat(pattern="yyyy/MM/dd HH:mm:ss") Date date2){
System.out.println("默认格式 date ==> " + date);
System.out.println("date1(yyyy-MM-dd) ==> " + date1);
System.out.println("date2(yyyy/MM/dd HH:mm:ss) ==> " + date2);
return "{'module':'data param'}";
}
请求示例:
date=2025/01/01date1=2025-01-01date2=2025/01/01 12:30:45
控制器响应
1 ) 概念
控制器方法返回值不同,对应不同的响应类型:
- 返回
String且不加@ResponseBody→ 跳转到对应页面。 - 返回 String 且加
@ResponseBody→ 直接将字符串写入响应体。 - 返回实体类或集合,加
@ResponseBody→ 转为 JSON 输出。
1 ) 页面跳转
@RequestMapping("/toJumpPage")
public String toJumpPage(){
System.out.println("跳转页面");
return "page.jsp"; // 根据视图解析器找到 /page.jsp
}
项目中需要配置视图解析器(此处未展开),通常返回逻辑视图名。
2 ) 文本响应
@RequestMapping("/toText")
@ResponseBody
public String toText(){
System.out.println("返回纯文本数据");
return "response text";
}
此时 @ResponseBody 告诉框架不要去找页面,而是直接输出返回的字符串。
3 ) JSON 响应
返回单个 POJO 对象
@RequestMapping("/toJsonPOJO")
@ResponseBody
public User toJsonPOJO(){
User user = new User();
user.setName("wf");
user.setAge(15);
return user;
}
返回结果自动转为 JSON 对象。
返回 POJO 集合
@RequestMapping("/toJsonList")
@ResponseBody
public List<User> toJsonList(){
List<User> userList = new ArrayList<>();
User user1 = new User();
user1.setName("小明");
user1.setAge(15);
userList.add(user1);
User user2 = new User();
user2.setName("黑马程序员");
user2.setAge(12);
userList.add(user2);
return userList;
}
返回结果自动转为 JSON 数组。
核心注解与配置
| 注解/配置 | 作用 |
|---|---|
@ResponseBody | 将返回的对象/集合写进响应体,并触发类型转换(对象→JSON) |
@EnableWebMvc | 启用 Spring MVC 高级功能,包括 JSON 消息转换 |
jackson-databind 依赖 | 提供 JSON 与对象之间的转换实现 |
4 ) 类型转换器接口
背后执行转换的核心是 HttpMessageConverter 接口。它负责将 HTTP 消息与 Java 类型相互转换。Jackson 实现类 MappingJackson2HttpMessageConverter 通过 @EnableWebMvc 自动被注册。
核心流程与总结
请求处理总流程
总结
本文从 Spring MVC 基础出发,介绍了:
- 请求路径映射:
@RequestMapping类与方法的组合应用。 - 参数传递:普通参数、POJO、嵌套 POJO、数组、集合,以及不同名参数绑定 @RequestParam。
- JSON 交互:
@EnableWebMvc+@RequestBody实现 JSON 请求数据的接收,以及 -@ResponseBody结合 Jackson 实现 JSON 响应。 - 日期参数:
@DateTimeFormat自定义格式。 - 响应处理:页面跳转、文本响应、JSON 响应,背后依赖
HttpMessageConverter进行类型转换。
掌握这些技能,即可应对日常开发中 90% 的请求与响应场景,为后续深入 RESTful 开发打下坚实基础。
5868



被折叠的 条评论
为什么被折叠?



