Apache BeanUtils工具介绍
beanutils,顾名思义,是java bean的一个工具类,可以帮助我们方便的读取(get)和设置(set)bean属性值、动态定义和访问bean属性;细心的话,会发现其实JDK已经提供了一个java.beans包,同样可以实现以上功能,只不过使用起来比较麻烦,所以诞生了apache commons beanutils;看源码就知道,其实apache commons beanutils就是基于jdk的java.beans包实现的。
maven:
<dependency><groupId>commons-chain</groupId><artifactId>commons-chain</artifactId><version>1.2</version>
</dependency>
commons-chain包主要有以下三个工具类:BeanUtils、PropertyUtils、ConvertUtils
1、设置、访问Bean的属性
1.1)javabean一般有以下几个特性:
1)类必须是public访问权限,且需要有一个public的无参构造方法,之所以这样主要是方便利用Java的反射动态创建对象实例:
Class beanClass = Class.forName(className);
Object beanInstance = beanClass.newInstance();
2)由于javabean的构造方法是无参的,所以我们的bean的行为配置(即设置bean的属性值)不能在构造方法完成,必须通过set方法来设置属性值。这里的setter方法会按一定的约定来命名,如setHireDate、setName。。。
3)读取和设置bean属性值的命名约定,即getter方法和setter方法,不过这里需要特别注意boolean类型的约定,如下示例:
private String firstName;
private String lastName;
private Date hireDate;
private boolean isManager;
public String getFirstName();
public void setFirstName(String firstName);
public String getLastName();
public void setLastName(String lastName);
public Date getHireDate();
public void setHireDate(Date hireDate);
public boolean isManager();
public void setManager(boolean manager);
4)并不是必须为每个属性提供setter和getter方法,我们可以只定义一个属性的getter方法而不定义setter方法,这样的属性一般是只读属性;
1.2)实战
可以通过BeanUtils和PropertyUtils设置、获取Bean的属性。
1)PropertyUtils设置、获取属性:
- 基本数据类型:
- PropertyUtils.getSimpleProperty(Object, String)
- PropertyUtils.setSimpleProperty(Object, String, Object)
- 索引类型:
- PropertyUtils.getIndexedProperty(Object, String)
-
- PropertyUtils.getIndexedProperty(Object, String, int)
- PropertyUtils.setIndexedProperty(Object, String, Object)
- PropertyUtils.setIndexedProperty(Object, String, int, Object)
- Map类型:
- PropertyUtils.getMappedProperty(Object, String)
-
- PropertyUtils.getMappedProperty(Object, String, String)
- PropertyUtils.setMappedProperty(Object, String, Object)
- PropertyUtils.setMappedProperty(Object, String, String, Object)
- 嵌套类型:
- PropertyUtils.getNestedProperty(Object, String)
- PropertyUtils.setNestedProperty(Object, String, Object)
- 通用类型:
- PropertyUtils.getProperty(Object, String)
- PropertyUtils.setProperty(Object, String, Object)
示例:
//定义bean
@Data
@ToString
public class Course {private String name;private List<String> codes;private Map<String, Student> enrolledStudent = new HashMap<>();
}
@Data
@ToString
public class Student {private String name;
}//测试
Course course = new Course(); //该类必须是public的、且有默认构造方法String name = "Computer Science";
List<String> codes = Arrays.asList("CS", "CS01");//Simple Property
PropertyUtils.setSimpleProperty(course, "name", name);
PropertyUtils.setSimpleProperty(course, "codes", codes);
System.out.println(course);
String nameV = (String)PropertyUtils.getSimpleProperty(course, "name");
System.out.println(nameV);//Indexed Property
PropertyUtils.setIndexedProperty(course, "codes[1]", "CS02");
PropertyUtils.setIndexedProperty(course, "codes", 1, "CS03");
System.out.println(course);
String indexedProperty = (String)PropertyUtils.getIndexedProperty(course, "codes", 1);
String indexedProperty2 = (String)PropertyUtils.getIndexedProperty(course, "codes[1]");
System.out.println(indexedProperty + "," + indexedProperty2);Student student = new Student();
String studentName = "Joe";
student.setName(studentName);//Mapped Property
PropertyUtils.setMappedProperty(course, "enrolledStudent(ST-1)", student);
PropertyUtils.setMappedProperty(course, "enrolledStudent", "ST-1", student);
System.out.println(course);
Student mappedProperty = (Student)PropertyUtils.getMappedProperty(course, "enrolledStudent", "ST-1");
Student mappedProperty2 = (Student)PropertyUtils.getMappedProperty(course, "enrolledStudent(ST-1)");
System.out.println(mappedProperty + "," + mappedProperty2);//Nested Property
PropertyUtils.setNestedProperty(course, "enrolledStudent(ST-1).name", "Joe_1");
String nameValue = (String) PropertyUtils.getNestedProperty(course, "enrolledStudent(ST-1).name");
//等价于 String name = course.getEnrolledStudent("ST-1").getName();
System.out.println(nameValue);
以上还可以使用下面的方式:
private static void test1_1() throws Exception {Course course = new Course();String name = "Computer Science";List<String> codes = Arrays.asList("CS", "CS01");//Simple PropertyPropertyUtils.setProperty(course, "name", name);PropertyUtils.setProperty(course, "codes", codes);System.out.println(course);String nameV = (String)PropertyUtils.getProperty(course, "name");System.out.println(nameV);//Indexed PropertyPropertyUtils.setProperty(course, "codes[1]", "CS02");System.out.println(course);Student student = new Student();String studentName = "Joe";student.setName(studentName);//Mapped PropertyPropertyUtils.setProperty(course, "enrolledStudent(ST-1)", student);System.out.println(course);//Nested PropertyPropertyUtils.setProperty(course, "enrolledStudent(ST-1).name", "Joe_1");String nameValue = (String) PropertyUtils.getProperty(course, "enrolledStudent(ST-1).name");System.out.println(nameValue);
}
2)BeanUtils设置、获取属性:
BeanUtils只有以下两个方法来设置、获取属性
- BeanUtils.getProperty(Object, String)
- BeanUtils.setProperty(Object, String, Object)
示例:
private static void test1_2() throws Exception {Course course = new Course();String name = "Computer Science";List<String> codes = Arrays.asList("CS", "CS01");//Simple PropertyBeanUtils.setProperty(course, "name", name);BeanUtils.setProperty(course, "codes", codes);System.out.println(course);String nameV = (String)BeanUtils.getProperty(course, "name");System.out.println(nameV);//Indexed PropertyBeanUtils.setProperty(course, "codes[1]", "CS02");System.out.println(course);Student student = new Student();String studentName = "Joe";student.setName(studentName);//Mapped PropertyBeanUtils.setProperty(course, "enrolledStudent(ST-1)", student);System.out.println(course);//Nested PropertyBeanUtils.setProperty(course, "enrolledStudent(ST-1).name", "Joe_1");String nameValue = (String) BeanUtils.getProperty(course, "enrolledStudent(ST-1).name");System.out.println(nameValue);
}
2、拷贝Bean的属性
2.1)BeanUtils有一下两个方法:
- populate:把Map里的键值对值拷贝到bean的属性值中;
- copyProperties:拷贝一个bean的属性到另外一个bean中,注意是浅拷贝
注意:populate和copyProperties的区别,对于Integer、Float、Boolean类型前者(populate)对于null值,在拷贝到Bean的属性后会变成默认值。
1)populate:
//bean定义
import java.util.Date;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
public class Employee {private Integer id;private String name;private Boolean isGood;private Float score;private Date createTime;public Employee(Integer id, String name, Boolean isGood, Float score, Date createTime) {this.id = id;this.name = name;this.isGood = isGood;this.score = score;this.createTime = createTime;}
}
//测试
Map<String, Object> map = new HashMap<>(2);
map.put("id", null);
map.put("name", "employee1");
map.put("isGood", null);
map.put("createTime", new Date()); //如果是null,会报错
map.put("add", "add1");
// map > obj
Employee e = new Employee();
BeanUtils.populate(e, map);
System.out.println(e); //Employee(id=0, name=employee1, isGood=false, createTime=Tue Aug 15 10:42:14 CST 2023)//支持类型转换
Map<String, Object> map = new HashMap<>(5);
map.put("id", "123");
map.put("name", 1.9);
map.put("isGood", "2");
map.put("score", null);
map.put("createTime", new Date());
map.put("add", "add1");
// map > obj
Employee e = new Employee();
BeanUtils.populate(e, map);
System.out.println(e); //Employee(id=123, name=1.9, isGood=false, score=1.0, createTime=Tue Aug 15 12:34:41 CST 2023)
说明:
- 对于Integer、Float、Boolean类型,如果是null,则转成bean的属性后会变成默认值(0,0.1,false)
- 对于Date类型,如果是null或者其他类型,转成bean的时候会报错,需要使用ConvertUtils进行类型转换(见下面)
- 支持类型转换:比如Integer和String之间
2)copyProperties:
有另外一个对象(类型和Employee不同)
@Data
public class Employee2 {private Integer id;private String name;private String isGood;private String score;private String createTime;private Float f1;
}
测试
private static void test2_1() throws Exception {Employee ee = new Employee(null, "employee2", null, null, null);Employee2 e1 = new Employee2();BeanUtils.copyProperties(e1, ee);System.out.println(e1); //Employee2(id=null, name=employee2, isGood=null, score=null, createTime=null, f1=null)Employee ee2 = new Employee(1, "employee2", true, 4.3f, new Date());Employee2 e2 = new Employee2();BeanUtils.copyProperties(e2, ee2);System.out.println(e2); //Employee2(id=1, name=employee2, isGood=true, score=4.3, createTime=Tue Aug 15 11:45:06 CST 2023, f1=null)
}
说明:
- 对于Integer、Float、Boolean、Date类型,如果是null,拷贝后也是null
- 支持类型转换:两个bean只要属性名一样,类型可转换即可拷贝。比如Integer、Float、Boolean类型转成String
2.2)PropertyUtils进行属性拷贝:
1)和BeanUtils区别:
- PropertyUtils只支持两个Bean之间的属性拷贝,不支持Map到Bean的
- PropertyUtils在两个Bean之间进行属性拷贝时,必须要保证名字和类型都一样才行,否则会报错。BeanUtils在进行属性拷贝时,名字一样,类型可转换即可。
Employee ee = new Employee(null, "employee2", null, null, null);
Employee2 e1 = new Employee2();
PropertyUtils.copyProperties(e1, ee);
System.out.println(e1); //Employee2(id=null, name=employee2, isGood=null, score=null, createTime=null, f1=null)Employee ee2 = new Employee(1, "employee2", true, 4.3f, new Date());
Employee2 e2 = new Employee2();
PropertyUtils.copyProperties(e2, ee2);
System.out.println(e2); //报错
报错信息:
2)说明:
- PropertyUtils不支持类型转换。
- 对于null值,PropertyUtils拷贝后也是null
3、ConvertUtils自定义类型转换
1)DateConverter:
DateConverter继承DateTimeConverter,是beanutils包中自带的时间类型转换,包含了:
示例
DateConverter converter = new DateConverter();
converter.setPattern("yyyy-MM-dd");
ConvertUtils.register(converter, java.util.Date.class);Map<String, Object> map = new HashMap<>(5);
map.put("id", 1);
map.put("name", "testConvertUtils");
map.put("isGood", false); //可以是Integer或String,1或"1" true 其他表示false,null表示false
map.put("score", 1.1f);
map.put("createTime", "2023-08-15");
map.put("add", "add1");// map > obj
Employee e = new Employee();
BeanUtils.populate(e, map);
System.out.println(e); //Employee(id=1, name=testConvertUtils, isGood=false, score=1.1, createTime=Tue Aug 15 00:00:00 CST 2023)
2)自定义:
ConvertUtils.register(new Converter() {public Object convert(Class type, Object value) {SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");try {return simpleDateFormat.parse(value.toString());} catch (Exception e) {e.printStackTrace();}return null;}
}, Date.class);
Employee e1 = new Employee();
BeanUtils.setProperty(e1, "createTime", "2022-09-09");
System.out.println(e1.getCreateTime()); //Fri Sep 09 00:00:00 CST 2022
说明:对于setProperty,如果存在时间类型,需要自定义转换器。
相关文章:

Apache BeanUtils工具介绍
beanutils,顾名思义,是java bean的一个工具类,可以帮助我们方便的读取(get)和设置(set)bean属性值、动态定义和访问bean属性;细心的话,会发现其实JDK已经提供了一个java.beans包,同样可以实现以上功能&…...

java 原子操作 笔记
目录 java 变量原子操作 java byte[] 原子操作 java 变量原子操作 public class Counter {private int count 0;public synchronized void increment() {count;}public synchronized int getCount() {return count;} } java byte[] 原子操作 public class SharedArray {pr…...

什么是线程安全性问题?Java中有哪些常用的同步机制来解决线程安全性问题?
线程安全性问题是指在多线程环境下,多个线程同时访问和修改共享数据时可能引发的数据不一致、竞态条件和并发访问异常等问题。线程安全性问题的主要原因是多个线程之间的并发执行,导致数据的访问和修改顺序不确定,从而产生不一致的结果。 为…...

Gitlab 安装全流程
Version:gitlab-ce:16.2.4-ce.0 简介 Gitlab 是一个开源的 Git 代码仓库系统,可以实现自托管的 Github 项目,即用于构建私有的代码托管平台和项目管理系统。系统基于 Ruby on Rails 开发,速度快、安全稳定。它拥有与 Github 类似…...

pdf转word最简单方法~
pdf转word最简单方法!pdf转word最简单方法我们都知道,PDF文件是一种只读文件格式,无法按照需求对PDF文件进行更改与编辑,从而影响到了PDF文件的使用。所以,我们需要将PDF文件转换为word文档,以此来保证文件…...

Android 9.0 WiFi 扫描结果上报和获取流程
本文是对wifi扫描结果上报和获取过程的java层代码流程梳理总结。 我们先分析扫描成功的上报和获取过程。 一、WiFi扫描成功的上报和获取过程 WiFi扫描成功的上报和获取大致是由三条不连贯流程组成的,分别是通知framework和WifiTracker获取扫描结果以及应用主动获取…...

Java 项目日志实例:Log4j2
点击下方关注我,然后右上角点击...“设为星标”,就能第一时间收到更新推送啦~~~ Apache Log4j 2 是对 Log4j 的升级,与其前身 Log4j 1.x 相比有了显着的改进,并提供了许多 Logback 可用的改进,同时支持 JCL 以及 SLF4J…...

Effective C++条款14——在资源管理类中小心coping行为(资源管理)
条款13导入这样的观念:“资源取得时机便是初始化时机”(Resource Acquisitionls Initialization; RAII),并以此作为“资源管理类”的脊柱,也描述了auto_ ptr和tr1::shared ptr如何将这个观念表现在 heap-based资源上。然而并非所有资源都是heap-based&am…...

【网络教程】如何创建/添加钉钉机器人以及如何获取机器人的Token/Secret
文章目录 创建钉钉机器人添加钉钉机器人获取机器人的Token/Secret相关网站创建钉钉机器人 这里以PC端的操作为例,按照如下操作进行 访问 钉钉开放平台选择机器人选项卡,点击右上角的创建应用,这里会有一个弹窗,我这里选择的是继续使用旧版,如图按照要求填写相关信息创建自…...

wx原生微信小程序入门常用总结
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、定义值和修改值1、定义值2、修改值(1)代码(2)代码说明(3)注意点 二、点击事件三、微…...

制作一个专属于安防监控业的小程序商城
随着科技的发展和人们生活水平的提高,安防监控设备在我们的日常生活中起到了越来越重要的作用。因此,建立一个安防监控设备商城小程序就变得尤为重要。下面将介绍如何建立这样一个小程序。 第一步,登录乔拓云平台后台,进入商城管理…...

基于java羽毛球馆管理系统设计与实现
摘 要 时代的变化速度实在超出人类的所料,21世纪,计算机已经发展到各行各业,各个地区,它的载体媒介-计算机,大众称之为的电脑,是一种特高速的科学仪器,比人类的脑袋要灵光无数倍,什么…...

安装elasticsearch8.9.0及修改配置
安装es流程 打开文件,添加以下行 vim /etc/sysctl.conf vm.max_map_count=262144重启生效 sysctl -p创建用户 useradd es passwd es修改es目录所属用户 chown -R es:es /opt/elasticsearch-8.9.0如果内存不足,可以修改es的初始化内存和Max内存,修改文件/opt/elasticsearch-8…...

如何构建高效的接口自动化测试框架?看完你就会了...
在选择接口测试自动化框架时,需要根据团队的技术栈和项目需求来综合考虑。对于测试团队来说,使用Python相关的测试框架更为便捷。无论选择哪种框架,重要的是确保 框架功能完备,易于维护和扩展,提高测试效率和准确性。今…...

53 | 金融行业股票销售指标分析
金融行业股票销售指标分析 引言: 金融行业中的股票销售指标分析是评估股票市场表现、投资者行为以及交易平台效果的重要手段。通过深入分析关键的销售指标,投资者、金融机构和交易平台可以更好地了解市场趋势,作出明智的投资决策,优化交易策略。本文将探讨金融行业股票销售…...

qiuzhiji1
前言:记录一下毕业后的求职历程 背景:18级 湖北理工学院计算机学院(黄石) 网络工程 本文初次撰写于2023年8月17日,正处于离职找工作的空档期,部分经历可能记不清了。所有内容尽量保证了客观,主要是分享一下自己的经历,顺带锻炼文字能力。 文章会不定期更新,较新的日期会…...

使用VisualStudio制作上位机(二)
文章目录 使用VisualStudio制作上位机(二)第三部分:GUI内部函数设计使用VisualStudio制作上位机(二) Author:YAL 第三部分:GUI内部函数设计 事件添加 给窗体或窗体按钮相关的操作添加事件有两种方式,事件的名字直白的表面了这是什么事件。 直接双击界面,自动生成窗…...

Datawhale AI夏令营 - 用户新增预测挑战赛 | 学习笔记
数据分析与可视化 为了拟合出更好的结果就要了解训练数据之间的相互关系,进行数据分析是必不可少的一步 导入必要的库 # 导入库 import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns pandas库是一个强大的分析结构化…...

HarmonyOS/OpenHarmony(Stage模型)卡片开发AbilityStage组件容器
AbilityStage是一个Module级别的组件容器,应用的HAP在首次加载时会创建一个AbilityStage实例,可以对该Module进行初始化等操作。 AbilityStage与Module一一对应,即一个Module拥有一个AbilityStage。 DevEco Studio默认工程中未自动生成Abilit…...

利用torchvision库实现目标检测与语义分割
一、介绍 利用torchvision库实现目标检测与语义分割。 二、代码 1、目标检测 from PIL import Image import matplotlib.pyplot as plt import torchvision.transforms as T import torchvision import numpy as np import cv2 import randomCOCO_INSTANCE_CATEGORY_NAMES …...

基于决策树(Decision Tree)的乳腺癌诊断
决策树(DecisionTree)学习是以实例为基础的归纳学习算法。算法从--组无序、无规则的事例中推理出决策树表示形式的分类规则,决策树也能表示为多个If-Then规则。一般在决策树中采用“自顶向下、分而治之”的递归方式,将搜索空间分为若千个互不相交的子集,在决策树的内部节点(非叶…...

前端面试的计算机网络部分(2)每天10个小知识点
目录 系列文章目录前端面试的计算机网络部分(1)每天10个小知识点 知识点11. DNS 完整的查询过程递归查询过程:迭代查询过程: 12. OSI 七层模型13. TCP 的三次握手和四次挥手三次握手(Three-Way Handshake)&…...

【LeetCode】224. 基本计算器
224. 基本计算器(困难) 方法:双栈解法 思路 我们可以使用两个栈 nums 和 ops 。 nums : 存放所有的数字ops :存放所有的数字以外的操作,/- 也看做是一种操作 然后从前往后做,对遍历到的字符做…...

服务器数据恢复-EVA存储磁盘故障导致存储崩溃的数据恢复案例
EVA系列存储是一款以虚拟化存储为实现目的的中高端存储设备。EVA存储中的数据在EVA存储设备工作过程中会不断进行迁移,如果运行的任务比较复杂,EVA存储磁盘负载加重,很容易出现故障的。EVA存储通过大量磁盘的冗余空间和故障后rss冗余磁盘动态…...

【stylus】通过css简化搜索页面样式
发现stylus专门修改样式的插件后,发现之前写JS调整样式的方式是在太蠢了,不过有一些交互的东西还是得用JS,例如设置按钮来交互显示功能,或记录功能等。插件可以让简化网站变得简单,而且可以实时显示,真的不…...

【官方中文文档】Mybatis-Spring #使用 SqlSession
使用 SqlSession 在 MyBatis 中,你可以使用 SqlSessionFactory 来创建 SqlSession。 一旦你获得一个 session 之后,你可以使用它来执行映射了的语句,提交或回滚连接,最后,当不再需要它的时候,你可以关闭 s…...

Redis三种持久化方式详解
一、Redis持久性 Redis如何将数据写入磁盘 持久性是指将数据写入持久存储,如固态磁盘(SSD)。Redis提供了一系列持久性选项。其中包括: RDB(快照):RDB持久性以指定的时间间隔执行数据集的时间点…...

17.2 【Linux】通过 systemctl 管理服务
systemd这个启动服务的机制,是通过一支名为systemctl的指令来处理的。跟以前 systemV 需要 service / chkconfig / setup / init 等指令来协助不同, systemd 就是仅有systemctl 这个指令来处理而已。 17.2.1 通过 systemctl 管理单一服务 (s…...

第 7 章 排序算法(3)(选择排序)
7.6选择排序 7.6.1基本介绍 选择式排序也属于内部排序法,是从欲排序的数据中,按指定的规则选出某一元素,再依规定交换位置后达到排序的目的。 7.6.2选择排序思想: 选择排序(select sorting)也是一种简单的排序方法…...

Less文件可以做哪些复杂操作
在Less文件中,你可以进行许多复杂的操作来增强样式表的功能和灵活性。以下是一些常见的操作: 变量(Variables):使用符号定义和使用变量,可以在整个样式表中重复使用相同的值,以便轻松修改和维护…...