浅谈SpringMVC参数处理过程
字数 2382 2025-08-06 08:34:54
Spring MVC 参数处理机制深度解析
0x00 概述
Spring MVC 通过参数解析机制简化了传统 Java Web 开发中通过 HttpServletRequest.getParameter() 获取请求参数的方式。开发者只需在 Controller 方法中定义参数,Spring MVC 会自动完成参数解析、类型转换和校验。
0x01 请求参数解析流程
1.1 请求处理入口
-
DispatcherServlet.service():Servlet 容器接收请求后调用
- 位于
FrameworkServlet父类中实现 - 除 PATCH 方法外,其他 HTTP 方法都通过
HttpServlet.service()处理
- 位于
-
processRequest():根据请求方法调用对应处理
- GET →
doGet() - POST →
doPost() - 其他方法类似
- GET →
-
doDispatch():核心分发方法
- 处理 multipart 请求
- 获取 URL 与 Handler 的映射关系
- 根据 URI 找到对应的 Controller 和方法
1.2 Handler 适配与执行
-
获取 HandlerAdapter:找到适合处理当前请求的适配器
- 调用
handle()方法处理请求 - 实际执行
handleInternal()
- 调用
-
请求检查与会话同步
- 检查请求有效性
- 必要时在会话级别进行同步
- 获取 HttpSession
- 获取互斥对象进行同步
-
invokeHandlerMethod():执行实际请求处理
- 封装
ServletWebRequest(包含HttpServletRequest和HttpServletResponse) - 获取
DataBinderFactory和ModelFactory - 创建
ServletInvocableHandlerMethod执行方法调用
- 封装
1.3 参数解析核心过程
-
invokeForRequest():调用 Controller 方法
- 通过
getMethodArgumentValues()获取方法参数值
- 通过
-
参数解析步骤:
- 获取方法参数列表
- 遍历参数列表:
- 检查
providedArgs中是否有预定义参数 - 使用合适的参数解析器解析参数
- 检查
-
解析器查找机制:
- 检查缓存中是否有适用的解析器
- 遍历已配置的解析器列表(约28个)
- 调用解析器的
supportsParameter()判断是否支持当前参数 - 找到后缓存并返回解析器
-
参数解析执行:
- 调用解析器的
resolveArgument()方法 - 处理参数类型转换、绑定和验证
- 调用解析器的
0x02 参数解析器详解
2.1 常见解析器类型
-
RequestParamMapMethodArgumentResolver
- 解析条件:
@RequestParam注解 + Map 类型参数 - 示例:
@RequestParam Map<String, String> params
- 解析条件:
-
RequestParamMethodArgumentResolver
- 解析条件:
@RequestParam注解 + 非 Map 类型- 基本类型及其包装类(String, Number, Date 等)
- 可选请求参数(
required=false或Optional)
- 示例:
@RequestParam("param") String param @RequestParam(required = false) Integer id @RequestParam Optional<String> name
- 解析条件:
-
PathVariableMethodArgumentResolver
- 解析
@PathVariable注解参数
- 解析
-
RequestPartMethodArgumentResolver
- 解析
@RequestPart注解参数(文件上传等)
- 解析
2.2 参数解析细节
2.2.1 普通参数解析
-
resolveName() 方法处理流程:
- 获取原生
HttpServletRequest - 处理 multipart 请求(文件上传)
- 普通参数通过
request.getParameterValues(name)获取
- 获取原生
-
HTTP 参数污染(HPP)处理:
- Tomcat 默认取第一个参数值
- Spring 返回参数值数组
- 示例:
param=1¶m=2→ 返回["1", "2"]
2.2.2 安全绕过示例
-
SQL 注入绕过技术:
- 利用参数解析特性拆分恶意 payload
- 示例:
1/(case+when+ascii(substr(user,1,1))=112+then+1+else+0+end) - 拆分方式:
param=1/(case+when+ascii(substr(user¶m=1,1,1))=112+then+1+else+0+end) - 效果:
- ASCII 111 → 触发除零异常
- ASCII 112 → 正常返回
-
WAF 绕过原理:
- 利用解析器返回
Object类型的灵活性 - 拆分敏感函数(如
substr())绕过关键词检测
- 利用解析器返回
0x03 其他重要解析器
-
MatrixVariableMethodArgumentResolver
- 解析矩阵变量(URI 路径中的
;分隔参数)
- 解析矩阵变量(URI 路径中的
-
RequestHeaderMethodArgumentResolver
- 解析
@RequestHeader注解参数
- 解析
-
CookieValueMethodArgumentResolver
- 解析
@CookieValue注解参数
- 解析
-
ModelAttributeMethodProcessor
- 处理
@ModelAttribute注解参数
- 处理
0x04 总结
Spring MVC 参数处理机制的核心特点:
- 灵活的参数解析:通过多种解析器支持各种参数类型和注解
- 自动类型转换:基本类型、包装类、日期等自动转换
- 扩展性强:可自定义参数解析器实现特殊需求
- 安全考量:需注意参数解析过程中的安全边界,特别是 HPP 等场景
开发建议:
- 明确参数类型和注解使用
- 对敏感参数进行额外验证
- 了解解析器特性以避免意外行为
- 在安全防护中考虑参数解析机制的影响