Spring 类型转换、数值绑定与验证(一)— DataBinder

这篇具有很好参考价值的文章主要介绍了Spring 类型转换、数值绑定与验证(一)— DataBinder。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

 DataBinder 是Spring用于数据绑定、类型转换及验证的类。使用场景有:1)xml配置文件定义bean,Spring 内部使用DataBinder 来完成属性的绑定;2)Web请求参数绑定,在Spring MVC 中,Controller的方法参数通常会自动绑定到请求参数中,主要用DataBinder来完成。3)自定义数据绑定,可手动创建DataBinder 对象,为其设置校验器和转换器,来满足特定需求。

1 DataBinder 类

Spring 类型转换、数值绑定与验证(一)— DataBinder,Spring,java,spring,spring boot,mvc,开发语言

图 DataBinder UML图

PropertyEditorRegistry:

PropertyEditor 注册商,用来管理及保存PropertyEditor(JDK自带接口,支持各种不同的方式来显示和更新属性值,比如在Spring的xml中,配置Bean 时,把字符串类型转化成对应的Integer、File等类型)。定义了注册PropertyEditor 的接口。

TypeConverter:

定义了类型转化方法。

public class DataBinderTest {

    public static void main(String[] args) throws BindException {
        User user = new User();
        DataBinder binder = new DataBinder(user);
        MutablePropertyValues propertyValues = new MutablePropertyValues();
        propertyValues.add("username","黄先生");
        propertyValues.add("address.province","广东");
        propertyValues.add("address.city","深圳");
        propertyValues.add("infos['job']","程序员");
        propertyValues.add("age",28);
        binder.bind(propertyValues);
        System.out.println(user); // User{username='黄先生', age=28, address=Address{province='广东', city='深圳'}, infos={job=程序员}}
    }

    public static class User {
        private String username;
        private Integer age;
        private Address address;

        private Map<String,Object> infos;

        public void setUsername(String username) {
            this.username = username;
        }

        public String getUsername() {
            return username;
        }

        public void setAge(Integer age) {
            this.age = age;
        }

        public Integer getAge() {
            return age;
        }

        public void setAddress(Address address) {
            this.address = address;
        }

        public Address getAddress() {
            return address;
        }

        public Map<String, Object> getInfos() {
            return infos;
        }

        public void setInfos(Map<String, Object> infos) {
            this.infos = infos;
        }

        @Override
        public String toString() {
            return "User{" +
                    "username='" + username + '\'' +
                    ", age=" + age +
                    ", address=" + address +
                    ", infos=" + infos +
                    '}';
        }
    }

    public static class Address {
        private String province;
        private String city;

        public void setProvince(String province) {
            this.province = province;
        }

        public String getProvince() {
            return province;
        }

        public void setCity(String city) {
            this.city = city;
        }

        public String getCity() {
            return city;
        }

        @Override
        public String toString() {
            return "Address{" +
                    "province='" + province + '\'' +
                    ", city='" + city + '\'' +
                    '}';
        }
    }
}

2 数值绑定过程

如上代码。使用了DataBinder的bind(PropertyValues pvs) 来将属性值绑定到目标对象中。

Spring 类型转换、数值绑定与验证(一)— DataBinder,Spring,java,spring,spring boot,mvc,开发语言

图 DataBinder的bind 方法

Spring 类型转换、数值绑定与验证(一)— DataBinder,Spring,java,spring,spring boot,mvc,开发语言

图 数据绑定过程中的方法调用

2.1 PropertyValues

PropertyValues 用于保存一个或多个Property的接口。MutablePropertyValues是其实现类。新增了对Property 新增、删除等操作。

2.1.1 Property

Spring 类型转换、数值绑定与验证(一)— DataBinder,Spring,java,spring,spring boot,mvc,开发语言

图 Property UML

AttributeAccessor: 定义了对象属性的访问及设置值等操作的接口。

AttributeAccessorSupport: 是AttributeAccessor 的实现类,这里的属性操作对象是一个Map类型。

BeanMetadataElement:定义了一个方法getSource(),用于获取Bean元数据的源对象。这个源对象通常是源文件信息。

BeanMetadataAttributeAccessor: 会覆盖AttributeAccessorSupport中设置和获取属性的方法,会将属性转换为BeanMetadataAttribute,目的是为了跟踪Bean定义的源对象。

BeanMetadataAttribute: 在Spring容器中,Bean的定义来源与多种不同的配置方式,例如XML、注解、配置类等。当Spring容器解析Bean的定义时,它会将源信息(如XML文件的路径、注解的位置等)与Bean的定义关联起来,这样,在后续处理中,如果需要对Bean的定义进行查找、修改或报告错误,Spring可以使用这个源信息。

Property:与BeanMetadataAttributeAccessor 不同的是,Property将属性和值封装在一个对象中,而不是使用Map对象来保存所有属性。这种设计提供了更大的灵活性和便利性,并允许处理索引属性以进行优化。

2.2 applyPropertyValues方法

在该方法中,执行下面语句来完成对目标对象的赋值:

getPropertyAccessor().setPropertyValues(mpvs, isIgnoreUnknownFields(), isIgnoreInvalidFields());

getPropertyAccessor()方法:

protected ConfigurablePropertyAccessor getPropertyAccessor() {
    return getInternalBindingResult().getPropertyAccessor();
}

getInternalBindingResult()方法:

protected AbstractPropertyBindingResult getInternalBindingResult() {
    if (this.bindingResult == null) {
       initBeanPropertyAccess();
    }
    return this.bindingResult;
}

调用关系为:

AbstractPropertyBindingResult.getPropertyAccessor() -> ConfigurablePropertyAccessor.setPropertyValues(参数) 完成对象属性赋值。

2.2.1 AbstractPropertyBindingResult

数据绑定的结果。BindingResult用于处理数据绑定的错误。主要用来收集、存储和管理在数据绑定过程中发生的错误。

Spring 类型转换、数值绑定与验证(一)— DataBinder,Spring,java,spring,spring boot,mvc,开发语言

图 AbstractPropertyBindingResult UML

AbstractPorpertyBindingResult 是一个抽象类,定义了一个抽象方法:getPropertyAccessor。返回ConfigurablePropertyAccessor类型。有两个实现类。

DirectFieldBindingResult

用于能直接访问的对象,而不是通过getter和setter方法访问的。

BeanPropertyBindingResult

默认实现,标准bean,通过getter和setter方法访问的。

表 AbstractPropertyBindingResult两个实现类

Spring 类型转换、数值绑定与验证(一)— DataBinder,Spring,java,spring,spring boot,mvc,开发语言

图 BeanPropertyBindingResult的getPropertyAccessor方法

Spring 类型转换、数值绑定与验证(一)— DataBinder,Spring,java,spring,spring boot,mvc,开发语言

图 BeanPropertyBindingResult 类的代码

PropertyAccessorFactory 是一个简单的工厂类,根据对象属性是否直接访问来创建对应的ConfigurablePropertyAccessor。

2.2.2 ConfigurablePropertyAccessor

提供了灵活的方式来访问和操作Bean对象的属性,并支持类型转化和属性编辑等功能。该接口新增了设置及获取ConversionService的方法。

Spring 类型转换、数值绑定与验证(一)— DataBinder,Spring,java,spring,spring boot,mvc,开发语言

图 ConfigurablePropertyAccessor接口 UML

PropertyAccessor接口:提供了可以访问命名属性(bean属性或对象中的字段)的接口。提供了对JavaBean属性的读取和写入操作。

Spring 类型转换、数值绑定与验证(一)— DataBinder,Spring,java,spring,spring boot,mvc,开发语言

图 PropertyAccessor 接口的方法

2.3 BeanWrapperImpl

为标准bean属性的访问实现的方法。还支持类型转化及自定义属性编辑等功能。

Spring 类型转换、数值绑定与验证(一)— DataBinder,Spring,java,spring,spring boot,mvc,开发语言

图 BeanWrapperImpl UML

BeanWrapper 继承了ConfigurablePropertyAccessor 接口,并增加了getWrappedInstance()获取将目标对象包装后的对象等方法。

AbstractNestablePropertyAccessor 主要用于支持嵌套属性的访问和类型转换。

2.3.1 AbstractNestablePropertyAccessor

Spring 类型转换、数值绑定与验证(一)— DataBinder,Spring,java,spring,spring boot,mvc,开发语言

图 AbstractPropertyAccessor 中的setPropertyValues方法部分截图

通过遍历属性值的List集合,来为每个属性值进行绑定。

Spring 类型转换、数值绑定与验证(一)— DataBinder,Spring,java,spring,spring boot,mvc,开发语言

图 AbstractNestablePropertyAccessor 中的setPropertyValue 方法

AbstractNestrablePropertyAccessor 中实现了父类抽象类的抽象方法setPropertyValue,来完成对单个属性值的绑定。

PropertyTokenHolder 是AbstractNestrablePropertyAccessor 的一个内部类,主要作用是解析和处理嵌套属性的名称,并将它们转换成可访问和操作的形式。

actualName

属性的实际名称。可能包含了方括号和引号等元素格式。

canonicalName

属性的规范名称。会去除属性名称中的方括号和引号,并将属性名称转换为规范的形式。例如,person[‘address’][‘city’]转换为address.city。

keys:String[]

保存了属性的键列表,例如上面的属性保存为[“address”,“city”]

表 PropertyTokenHolder 的字段

Spring 类型转换、数值绑定与验证(一)— DataBinder,Spring,java,spring,spring boot,mvc,开发语言

图 PropertyTokenHolder 代码

2.4 processLocalProperty方法完成属性类型转换及绑定

Spring 类型转换、数值绑定与验证(一)— DataBinder,Spring,java,spring,spring boot,mvc,开发语言

图 processLocalProperty方法中的关键代码

2.4.1 PropertyHandler

是一个抽象类,用于处理属性的读取和写入操作。定义了获取/设置属性值及检查属性是否可读可写的方法。其默认实现是BeanPropertyHandler, 针对JavaBean属性,使用JavaBean规范来操作属性。如果不是通过getter和setter方法访问的,则使用LocalPropertyHandler。文章来源地址https://www.toymoban.com/news/detail-836166.html

到了这里,关于Spring 类型转换、数值绑定与验证(一)— DataBinder的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • Spring MVC自定义类型转换器!!!

    Spring MVC自定义类型转换器!!!

    使用场景 在index.jsp里面添加日期类型 在pojo里面添加日期类型 测试 原因:我们前台传递的是字符串类型的参数,但是后台使用的是Date类型接收的。我们期望springmvc可以帮我们做数据类型的自动转换,显然没有做,所以我们需要自己自定义类型转换器。 解决方案: 定义一个

    2024年02月03日
    浏览(11)
  • Spring5学习随笔-生命周期、自定义类型转换器、后置处理Bean

    Spring5学习随笔-生命周期、自定义类型转换器、后置处理Bean

    学习视频:【孙哥说Spring5:从设计模式到基本应用到应用级底层分析,一次深入浅出的Spring全探索。学不会Spring?只因你未遇见孙哥】 指的是一个对象创建、存活、消亡的一个完整过程 由Spring负责对象的创建、存活、销毁,了解生命周期,有利于我们使用好Spring为我们创建

    2024年02月05日
    浏览(13)
  • Spring MVC获取参数和自定义参数类型转换器及编码过滤器

    Spring MVC获取参数和自定义参数类型转换器及编码过滤器

    目录   一、使用Servlet原生对象获取参数 1.1 控制器方法 1.2 测试结果 二、自定义参数类型转换器 2.1 编写类型转换器类 2.2 注册类型转换器对象  2.3 测试结果  三、编码过滤器 3.1 JSP表单 3.2 控制器方法 3.3 配置过滤器 3.4 测试结果  往期专栏文章相关导读  1. Maven系列专

    2024年02月10日
    浏览(10)
  • element 表单验证 深层验证绑定

    直接上代码 :prop 和prop 都可以,vue2和vue3或者是element、elementplus都可以用 table form:

    2024年02月14日
    浏览(10)
  • 【python基础】复杂数据类型-列表类型(数值列表)

    【python基础】复杂数据类型-列表类型(数值列表)

    视频讲解 列表非常适合用于存储数字集合,而Python提供了很多工具,可帮助我们高速地处理数字列表。 Python的range函数能够轻松的生成连续一系列数字。 其语法格式:range(起始值,终止值) 我们通过之前学习的for循环输出range函数生成的连续数字,编写程序如下所示: 我们通

    2024年02月07日
    浏览(14)
  • 数值类型翻转教学设计

    数值类型翻转教学设计

    任务描述 本关任务:编写一个能计算正方形面积的小程序。 相关知识 为了完成本关任务,你需要掌握: 1.输入函数 2.字符串转整数 3.数值运算 4.输出函数 任务描述 本关任务:编写一个能计算正方形面积的小程序。 相关知识 为了完成本关任务,你需要掌握: 1.输入函数 2

    2024年02月12日
    浏览(9)
  • Kotlin中的数值类型

    Kotlin中的数值类型

    在Kotlin中,Byte、Short、Int、Long、Float和Double是基本数据类型,用于表示不同范围和精度的数值。 Byte(字节):Byte类型是8位有符号整数类型,取值范围为-128到127。在Kotlin中,可以使用字面值或toByte()函数创建Byte类型变量。 示例代码: Short(短整型):Short类型是16位有符号整

    2024年02月07日
    浏览(11)
  • [python]数值类型

    表示的数值没有小数部分的数值,包含正整数、复数和0 整数类型有四种表示形式:二进制、八进制、十进制和十六进制 进制种类 引导符号 描述 十进制 无 默认情况,例如:365,786 二进制 0b或0B 由字符0和1组成,例如0b10101 八进制 0o或0O 由字符0到7组成,例如0o763 十六进制

    2024年01月19日
    浏览(6)
  • 21 - 数值类型

    数值类型是不可变类型(immutable type),它包括布尔类型、整数、浮点数与复数。 类型 英文名 构造方式 对应 构造函数 布尔 Boolean var = True bool bool() 整数 Integer var = 5 int int() 浮点数 Float var = 5.0 float float() 复数 Complex Number var = 5.0 + 0j complex complex() 在 Python 中有八种比较运算

    2024年02月19日
    浏览(9)
  • PostgreSQL-数值类型

    PostgreSQL-数值类型

    数值类型是最常用的几种数据类型之一,主要分为: 整型 浮点型 精确小数 数值类型列表 类型名称 存储空间 描述 范围 smallint 2字节 小范围的整数。 Oracle中没有此数值类型,使用number代替 -2^15 ~ 2^15-1 int 或 integer 4字节 常用的整数。 Oracle中integer等同于number(38),与此类型的意

    2024年02月02日
    浏览(9)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包