当前位置: 首页 > article >正文

35、请求处理-【源码分析】-自定义参数绑定原理

35、请求处理-【源码分析】-自定义参数绑定原理

自定义参数绑定原理主要涉及Spring Boot如何将HTTP请求中的参数自动绑定到控制器方法的自定义对象参数上。以下是详细的解析:

### 1. 参数解析器的选择

- **HandlerMethodArgumentResolverComposite**:

  - Spring Boot内部维护了一个`HandlerMethodArgumentResolverComposite`,它包含多个`HandlerMethodArgumentResolver`实例。

  - 当处理请求时,会遍历这些解析器,调用`supportsParameter`方法判断哪个解析器支持当前参数类型。

### 2. ServletModelAttributeMethodProcessor

- **支持参数类型**:

  - `ServletModelAttributeMethodProcessor`是关键的参数解析器,负责处理自定义POJO类型的参数。

  - 它通过`supportsParameter`方法判断参数是否满足以下条件:

    - 参数类型不是简单类型(如基本类型、集合等)。

    - 参数上存在`@ModelAttribute`注解,或没有该注解但`annotationNotRequired`为`true`。

### 3. 参数绑定过程

#### 创建目标对象

- **创建空对象**:

  - 调用`createAttribute`方法,通过反射创建自定义POJO类型的空对象实例。

#### 数据绑定

- **WebDataBinder**:

  - 使用`WebDataBinderFactory`创建`WebDataBinder`实例,用于将请求参数绑定到目标对象。

  - `WebDataBinder`内部维护了`Converters`集合,用于数据类型转换。

- **绑定请求参数**:

  - 调用`bindRequestParameters`方法,遍历请求中的所有参数。

  - 通过反射获取目标对象的属性,将请求参数值设置到对应的属性上。

  - 利用`Converters`进行类型转换,例如将字符串转换为日期类型。

### 4. 示例说明

假设有以下控制器方法:

```java

@PostMapping("/saveUser")

public String saveUser(Person person) {

    // ...

}

```

其中,`Person`类包含`name`、`age`和`birth`属性。

当提交表单数据:

```

name=张三&age=18&birth=2020-01-01

```

- **参数解析**:

  - `ServletModelAttributeMethodProcessor`识别`Person`类型参数。

  - 创建`Person`对象实例。

  - 使用`WebDataBinder`将请求参数绑定到`Person`对象的属性上。

### 5. 自定义类型转换

- **Converter注册**:

  - 若需要自定义类型转换,例如将特定格式的字符串转换为自定义类型,可以实现`Converter`接口。

  - 通过`WebMvcConfigurer`的`addFormatters`方法将自定义`Converter`注册到`FormattingConversionService`中。

### 6. 总结

自定义参数绑定原理:

1. **解析器选择**:通过`HandlerMethodArgumentResolverComposite`找到支持自定义POJO类型的`ServletModelAttributeMethodProcessor`。

2. **对象创建**:创建目标POJO对象实例。

3. **数据绑定**:利用`WebDataBinder`将请求参数绑定到对象属性,借助`Converters`进行类型转换。

通过理解这一原理,可以更灵活地处理各种复杂的请求参数绑定需求。

http://www.lryc.cn/news/2395511.html

相关文章:

  • 智绅科技——科技赋能健康养老,构建智慧晚年新生态
  • STM32通过KEIL pack包轻松移植LVGL,并学会使用GUI guider
  • day43 python Grad-CAM
  • 在 Ubuntu 上挂载其他硬盘的步骤
  • SQL的查询优化
  • MCU如何从向量表到中断服务
  • 物联网基础概念
  • Linux线程同步实战:多线程程序的同步与调度
  • 【MySQL】事务及隔离性
  • Leetcode 3566. Partition Array into Two Equal Product Subsets
  • yolo目标检测助手:具有模型预测、图像标注功能
  • 传统数据表设计与Prompt驱动设计的范式对比:以NBA投篮数据表为例
  • 2022 RoboCom 世界机器人开发者大赛(睿抗 caip) -高职组(国赛)解题报告 | 科学家
  • WIN11 Docker Desktop 安装问题解决
  • 网站服务器出现异常的原因是什么?
  • Python实例题:Python3实现图片转彩色字符
  • 同一机器下通过HTTP域名访问其他服务器进程返回504问题记录
  • 基于物联网(IoT)的电动汽车(EVs)智能诊断
  • JDBC+HTML+AJAX实现登陆和单表的CRUD
  • Leetcode 3568. Minimum Moves to Clean the Classroom
  • Kafka多线程Consumer
  • 从零开始的git学习
  • 【C++】位图详解(一文彻底搞懂位图的使用方法与底层原理)
  • Spring Boot 整合 JdbcTemplate,JdbcTemplate 与 MyBatis 的区别
  • sass基础语法
  • 【EF Core】 EF Core 批量操作的进化之路——从传统变更跟踪到无跟踪更新
  • [Go] Option选项设计模式 — — 编程方式基础入门
  • Vue 项目命名规范指南
  • 【笔记】开源通用人工智能代理 Suna 部署全流程准备清单(Windows 系统)
  • 海康工业相机SDK二次开发(VS+QT+海康SDK+C++)