文章目录
-
- 一、普通参数与基本注解
-
- [1.1 常用注解](#1.1 常用注解)
- [1.2 Servlet API参数](#1.2 Servlet API参数)
- [1.3 复杂参数](#1.3 复杂参数)
- [1.4 自定义对象参数](#1.4 自定义对象参数)
- 二、请求参数处理源码分析
- 三、自定义参数绑定
- 四、自定义参数绑定原理
- 总结
一、普通参数与基本注解
在SpringBoot的Web开发中,处理请求参数是最基础且常见的操作。SpringMVC提供了丰富的注解和机制来帮助我们方便地获取请求中的各类参数。
1.1 常用注解
- @PathVariable:用于获取URL路径中的变量值。
- @RequestHeader:用于获取HTTP请求头信息。
- @ModelAttribute:用于将请求参数绑定到模型对象。
- @RequestParam:用于获取HTTP请求参数。
- @MatrixVariable:用于获取URL中的矩阵变量。
- @CookieValue:用于获取Cookie值。
- @RequestBody:用于获取HTTP请求体内容,通常用于接收JSON或XML数据。
以下是一个使用多种注解的控制器方法示例:
java
@RestController
public class ParameterTestController {
@GetMapping("/car/{id}/owner/{username}")
public Map<String, Object> getCar(@PathVariable("id") Integer id,
@PathVariable("username") String name,
@PathVariable Map<String, String> pv,
@RequestHeader("User-Agent") String userAgent,
@RequestHeader Map<String, String> header,
@RequestParam("age") Integer age,
@RequestParam("interests") List<String> interests,
@RequestParam Map<String, String> params,
@CookieValue("_ga") String _ga,
@CookieValue("_ga") Cookie cookie) {
Map<String, Object> map = new HashMap<>();
map.put("id", id);
map.put("name", name);
map.put("pv", pv);
map.put("userAgent", userAgent);
map.put("header", header);
map.put("age", age);
map.put("interests", interests);
map.put("params", params);
map.put("_ga", _ga);
map.put("cookie", cookie);
return map;
}
}
1.2 Servlet API参数
SpringMVC支持在控制器方法中直接使用Servlet API中的对象作为参数,例如:
- WebRequest
- ServletRequest
- MultipartRequest
- HttpSession
- javax.servlet.http.PushBuilder
- Principal
- InputStream
- Reader
- HttpMethod
- Locale
- TimeZone
- ZoneId
1.3 复杂参数
除了基本参数类型,SpringMVC还支持一些复杂参数类型:
- Map
- Model(Map和Model中的数据会被放在request的请求域中,相当于调用request.setAttribute)
- Errors/BindingResult
- RedirectAttributes(用于重定向时携带数据)
- ServletResponse(response对象)
- SessionStatus
- UriComponentsBuilder
- ServletUriComponentsBuilder
1.4 自定义对象参数
SpringMVC支持将请求参数自动绑定到自定义对象,包括自动类型转换与格式化,以及级联封装(即对象中包含其他对象的情况)。
二、请求参数处理源码分析
SpringMVC通过HandlerAdapter组件来处理控制器方法的参数解析和调用。在SpringBoot中,默认配置了多个HandlerAdapter:
- RequestMappingHandlerAdapter:支持方法上标注@RequestMapping注解的处理器
- HandlerFunctionAdapter:支持函数式编程的处理器
- HttpRequestHandlerAdapter:支持HttpRequestHandler接口的处理器
- SimpleControllerHandlerAdapter:支持Controller接口的处理器
其中,RequestMappingHandlerAdapter是最常用的,它负责解析控制器方法中的各种参数注解。
参数解析过程
当请求到达DispatcherServlet时,它会找到匹配的处理器,然后通过合适的HandlerAdapter来调用处理器方法。参数解析的核心是HandlerMethodArgumentResolver接口,SpringMVC提供了多个实现类来处理不同类型的参数:
- PathVariableMethodArgumentResolver:处理@PathVariable注解
- RequestHeaderMethodArgumentResolver:处理@RequestHeader注解
- RequestParamMethodArgumentResolver:处理@RequestParam注解
- ServletCookieValueMethodArgumentResolver:处理@CookieValue注解
- RequestResponseBodyMethodProcessor:处理@RequestBody注解和@ResponseBody注解
以下是一个展示请求域参数传递的示例:
java
@Controller
public class RequestController {
// 取出请求域中的参数值的方法,并将请求参数传入到下一个请求
@GetMapping("goto")
public String goToPage(HttpServletRequest request) {
request.setAttribute("msg", "这是从controller传入的参数");
request.setAttribute("code", 200);
return "forward:/success"; // 转发到/success请求
}
@GetMapping("/params")
public String testParam(Map<String, Object> map,
Model model,
HttpServletRequest request,
HttpServletResponse response) {
map.put("hello", "world666");
model.addAttribute("world", "hello666");
request.setAttribute("message", "HelloWorld");
Cookie cookie = new Cookie("c1", "v1");
cookie.setDomain("localhost");
response.addCookie(cookie);
return "forward:/success";
}
@ResponseBody
@GetMapping("/success")
public Map success(@RequestAttribute(value = "msg", required = false) String msg,
@RequestAttribute(value = "code", required = false) Integer code,
HttpServletRequest request) {
Object msg1 = request.getAttribute("msg");
Object code1 = request.getAttribute("code");
Object hello = request.getAttribute("hello");
Object world = request.getAttribute("world");
Object message = request.getAttribute("message");
Map<String, Object> map = new HashMap<>();
map.put("reqMethod_msg", msg1); // 使用请求域中的参数
map.put("annotation_msg", msg); // 使用参数注解传入的参数
map.put("hello", hello);
map.put("world", world);
map.put("message", message);
return map;
}
}
在这个示例中,我们展示了如何通过HttpServletRequest设置请求域属性,以及如何通过@RequestAttribute注解或HttpServletRequest对象获取这些属性。当使用"forward"转发时,请求域中的属性会被保留到下一个请求中。
运行结果

我们来看一下cookie的值
三、自定义参数绑定

Person类
c
package com.web.bean;
import lombok.Data;
import java.util.Date;
/**
* @author cc
* @date 2020/11/23-16:09
*/
@Data
public class Person {
private String userName;
private Integer age;
private Date birth;
private Pet pet;
}
宠物类
c
package com.web.bean;
import lombok.Data;
@Data
public class Pet {
private String name;
private Integer age;
}
控制器接口方法
c
@RestController
public class ParameterTestController {
@PostMapping("/saveuser")
public Person saveUser(Person person){
return person;
}

点击提交按钮

四、自定义参数绑定原理
1、核心机制:Web数据绑定
1. 核心组件:WebDataBinder
- 功能:作为数据绑定的核心处理器,负责将HTTP请求参数(通常是字符串形式)的值绑定到目标JavaBean的对应属性上。
- 工作流程 :
- 接收请求参数(
String
类型)。 - 利用内置的转换服务(ConversionService) 和其管理的转换器(Converters) ,将字符串数据转换为目标属性所需的复杂数据类型(如
Integer
、Date
、File
或自定义对象)。 - 将转换后的数据填充(封装)到JavaBean中。
- 接收请求参数(
2. 基础架构:通用转换服务(GenericConversionService)
- 角色 :是类型转换系统的容器和调度中心。它是一个配置一次即可全局使用的服务。
- 管理 :内部维护了一个转换器(Converter)集合。这个集合包含了Spring默认提供的众多转换器(用于处理基本类型、集合等)以及开发者注册的自定义转换器。
- 职责 :当需要进行类型转换时,
GenericConversionService
会负责查找并调用合适的Converter
来执行实际的转换工作。
2、自定义转换:原理与实现
1. 目的
解决框架默认转换能力不足的问题。当Spring无法自动将请求参数(String
)转换为特定的、复杂的或自定义的目标类型时,就需要开发者介入,提供明确的转换规则。
2. 核心技术:Converter<S, T>
接口
- 定义:一个函数式接口,是类型转换策略的抽象。
- 泛型参数 :
S
(Source):源类型,即需要被转换的数据类型(在Web场景中通常是String
)。T
(Target):目标类型,即希望转换成的数据类型。
- 核心方法 :
T convert(S source)
- 开发者需要实现此方法,编写具体的转换逻辑,例如解析字符串、构造对象、设置属性等。
3. 实现步骤
- 创建转换器 :定义一个类,实现
Converter<S, T>
接口,并在convert
方法中完成从String
到目标对象(如Person
、Order
等)的转换逻辑。 - 注册转换器 :将自定义的
Converter
实例添加到Spring的ConversionService
中,使其生效。- 配置方式 :可以通过Java配置类(使用
@Bean
注解)或XML配置文件进行注册。
- 配置方式 :可以通过Java配置类(使用
- 自动应用 :注册成功后,当Spring MVC在处理数据绑定遇到相应类型的转换时,会自动调用这个自定义的
Converter
,无需在控制器中编写额外的解析代码。
3、核心关系图
HTTP Request (带有String参数)
|
v
[WebDataBinder] // 协调绑定过程
|
| 需要转换类型时调用
v
[GenericConversionService] // 转换服务管理中心
|
| 查找并委托给匹配的
v
[Converter<S, T>] // 执行实际转换工作的组件(内置的或自定义的)
|
v
目标类型的对象 (e.g., Integer, Date, CustomJavaBean)
|
v
填充到目标JavaBean中
小结
Spring通过 WebDataBinder
和 GenericConversionService
构成了一套强大且可扩展的数据绑定与类型转换体系。其默认实现已经覆盖了大部分常见场景。对于特殊需求,开发者可以通过实现 Converter<S, T>
接口来定义精确的转换规则,并通过注册将其融入框架原有的转换流程中。这种设计既保证了开箱即用的便利性,又提供了高度的灵活性,是Spring MVC处理复杂Web参数绑定的关键机制。
总结
SpringBoot通过SpringMVC提供了完整且强大的Web请求参数处理机制,其核心在于灵活的参数绑定和类型转换体系。
在基础层面,框架提供了丰富的注解支持,包括@PathVariable、@RequestParam、@RequestHeader等,能够方便地提取URL路径、查询参数、请求头等各类信息。同时支持直接使用Servlet API对象和Map、Model等复杂参数类型,满足不同场景的需求。
参数处理的核心由HandlerAdapter组件实现,特别是RequestMappingHandlerAdapter负责解析方法参数。其内部通过HandlerMethodArgumentResolver策略接口,使用不同的解析器实现类来处理各类注解和参数类型。
对于自定义对象绑定,Spring提供了WebDataBinder和GenericConversionService组成的类型转换体系。WebDataBinder负责协调整个绑定过程,而GenericConversionService作为转换器容器,管理着包括默认转换器和自定义转换器在内的转换器集合。当默认转换能力不足时,开发者可以通过实现Converter<S, T>接口来定义特定类型的转换规则,并通过注册到转换服务中融入框架原有的转换流程。
这种分层设计使得SpringBoot既能提供开箱即用的便利性,又能通过扩展机制满足各种复杂的数据绑定需求,体现了框架的高度灵活性和可扩展性。