
Spring MVC 参数映射学习笔记
Spring MVC 参数映射学习笔记
在 Spring MVC 中,控制器(Controller)负责处理用户的请求并返回响应。一个核心任务就是接收和解析请求中的参数。Spring MVC 提供了多种灵活的方式来将请求参数绑定到控制器方法的参数上,这个过程称为参数映射。
1. 通过 HttpServletRequest
对象获取
这是最基础、最原始的方式,直接使用Servlet API来获取参数。
@RequestMapping("param01")
public Map<String, String[]> param01(HttpServletRequest request) {
//1.获取请求参数
Map<String, String[]> map = request.getParameterMap();
return map;
}
注意事项:
- 返回的
Map<String, String[]>
中,值是一个字符串数组,因为一个参数名可能对应多个值(例如,复选框)。 - 需要手动进行类型转换,例如从
String
转换为Integer
或Date
。 - 这种方式与Servlet API耦合度较高,在纯粹的Spring MVC开发中不常用,但在需要访问底层请求对象(如获取请求头、Session等)时仍然很有用。
常用使用场景:
- 需要获取所有请求参数,但参数名不确定时。
- 需要访问除了请求参数之外的其他请求信息,如请求头(Header)、Cookies 或会话(Session)。
- 在一些遗留代码或需要与Servlet API进行深度交互的特定场景下使用。
2. 方法参数直接映射
Spring MVC 可以自动将请求参数按名称匹配到控制器方法的同名参数上。
@RequestMapping("/pararm03")
public Map<String,Object> pararm03(String uname, Integer age){
Map<String,Object> map = new HashMap<>();
map.put("uname", uname);
map.put("age", age);
return map;
}
注意事项:
- 参数名称必须完全一致。请求中的参数名(如
?uname=zhangsan&age=25
)必须与方法中的参数名(uname
,age
)相同。 - Spring MVC 会自动进行简单的类型转换。例如,将"25"自动转换为
Integer
类型的25。如果转换失败(如"abc"无法转为Integer
),会抛出异常。 - 如果请求中没有传递某个参数,对应的参数值会是
null
(对于对象类型)或默认值(对于基本数据类型,但可能引发异常,建议使用包装类型如Integer
)。
常用使用场景:
- 处理简单、参数数量较少的GET或POST请求。
- 当前后端参数命名规范统一时,这是最简洁、最直观的映射方式。
3. 通过 @RequestParam
注解映射
这是对直接映射的增强,提供了更多的控制选项,是处理单个参数时最常用的注解。
@RequestMapping("/pararm04")
public Map<String,Object> pararm04(
@RequestParam(value = "username", required = false) String uname,
@RequestParam(value = "age", defaultValue = "20") Integer age
){
Map<String,Object> map = new HashMap<>();
map.put("uname", uname);
map.put("age", age);
return map;
}
注意事项:
value
(或name
): 用于指定请求参数的名称。当方法参数名与请求参数名不一致时(例如前端传username
,后端用uname
接收),必须使用此属性。required
: 布尔类型,默认为true
。true
(默认): 表示该参数必须传递,否则会报400错误(Bad Request)。false
: 表示该参数是可选的,如果不传递,则参数值为null
。
defaultValue
: 字符串类型。如果请求中没有传递该参数,或者传递的值为空,则会使用这个默认值。注意,设置了defaultValue
后,required
属性会自动变为false
。
常用使用场景:
- 当前后端参数名称不一致时。
- 需要对参数进行校验,如设置某个参数为必传或可选。
- 希望为某个参数提供一个默认值,以简化客户端的请求。
4. 通过实体类(POJO)进行映射
当请求参数较多时,可以使用一个实体类来统一接收,使代码更加整洁和结构化。
@RequestMapping("/pararm05")
public User pararm05(User user){ // Spring MVC自动创建User对象并填充属性
return user;
}
注意事项:
- 属性名与参数名必须一致。Spring MVC会通过调用实体类的
setter
方法来注入属性值。例如,请求参数uname
会对应调用setUname()
方法。 - 实体类必须有一个无参构造函数,以便Spring MVC能够实例化它。
- 支持级联属性映射,例如
?address.city=beijing
可以映射到User
对象中Address
类型属性的city
字段。
常用使用场景:
- 表单提交,特别是当表单字段与数据库实体或业务模型相对应时。
- 当请求参数超过3-4个时,使用实体类可以极大地提高代码的可读性和可维护性。
- 适用于
application/x-www-form-urlencoded
或multipart/form-data
类型的请求。
5. 通过 @PathVariable
注解进行映射
用于从URL路径中动态获取参数,是实现RESTful风格API的关键。
// 请求URL: localhost:8080/param/pararm06/admin/123456
@RequestMapping("/pararm06/{username}/{pwd}")
public Map<String,Object> pararm06(@PathVariable("username") String uname, @PathVariable String pwd){
Map<String,Object> map = new HashMap<>();
map.put("uname", uname);
map.put("pwd", pwd);
return map;
}
注意事项:
@RequestMapping
的路径中必须使用占位符{...}
来定义变量。@PathVariable
注解的参数名需要和占位符名称一致。如果不一致,可以通过@PathVariable("占位符名")
来指定。@PathVariable
标记的参数默认为必传,因为它是URL路径的一部分。
常用使用场景:
- RESTful API设计,例如查询特定资源 (
/users/{id}
)、删除特定资源 (/products/{productId}
) 等。 - 当参数是资源的唯一标识符时,将其放在URL路径中比放在查询字符串中语义更清晰。
6. 通过 @RequestBody
注解获取请求体数据
用于接收HTTP请求体中的内容,通常是JSON或XML格式的数据。
// 接收JSON对象
@RequestMapping("/param07")
public User param07(@RequestBody User user){
return user;
}
// 接收JSON数组
@RequestMapping("param08")
public List<User> param08(@RequestBody List<User> users) {
return users;
}
注意事项:
- 一个请求方法中只能有一个
@RequestBody
注解,因为它会读取整个请求体。 - 前端请求方式通常为
POST
或PUT
,并且需要设置Content-Type
为application/json
(或application/xml
等)。 - Spring MVC需要配合相应的
HttpMessageConverter
(如MappingJackson2HttpMessageConverter
)来将JSON字符串反序列化为Java对象。通常,在引入spring-boot-starter-web
依赖后会自动配置好。 - 对于JSON到对象的映射,JSON对象的字段名需要和Java类的属性名一致(或通过Jackson的注解如
@JsonProperty
进行映射)。
常用使用场景:
- 前后端分离项目中,接收前端通过AJAX提交的JSON格式数据。
- 创建或更新资源时,客户端将资源的完整信息以JSON格式放在请求体中发送。
- 接收复杂的数据结构,如嵌套对象、对象列表等。
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 程序员Hanserwei
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果