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 Property
        PropertyUtils.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 Property
        PropertyUtils.setProperty(course, "codes[1]", "CS02");
        System.out.println(course);
        
        Student student = new Student();
        String studentName = "Joe";
        student.setName(studentName);
        
        //Mapped Property
        PropertyUtils.setProperty(course, "enrolledStudent(ST-1)", student);
        System.out.println(course);
        
        //Nested Property
        PropertyUtils.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 Property
        BeanUtils.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 Property
        BeanUtils.setProperty(course, "codes[1]", "CS02");
        System.out.println(course);
        
        Student student = new Student();
        String studentName = "Joe";
        student.setName(studentName);
        
        //Mapped Property
        BeanUtils.setProperty(course, "enrolledStudent(ST-1)", student);
        System.out.println(course);
        
        //Nested Property
        BeanUtils.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,如果存在时间类型,需要自定义转换器。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/84948.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Vue2.0+webpack 引入字体文件(eot,ttf,woff)

webpack.base.config.js 需要配置 {test:/\/(woff2?|eot|ttf|otf)(\?.*)?$/,loader: url-loader,options: {limit: 10000,name: utils.assetsPath(fonts/[name].[hash:7].[ext])}} 如果 Vue2.0webpack3.6引入字体文件&#xff08;eot&#xff0c;ttf&#xff0c;woff&…

[PyTorch][chapter 51][Auto-Encoder -1]

目录&#xff1a; 简介 损失函数 自动编码器的类型 一 AutoEncoder 简介&#xff1a; 自动编码器是一种神经网络&#xff0c;用于无监督学习任务.(没有标签或标记数据), 例如降维,特征提取和数据压缩. 主要任务&#xff1a; 1&#xff1a; 输入数据 …

SCSS 学习笔记 和 vscode下载live sass compiler插件配置

1、下载livelive sass compiler插件并配置 // 在 已有代码 下面 添加下面 代码&#xff0c;一般刚刚下载打开最后一行是&#xff1a;// "liveSassCompile.settings.autoprefix": [],// 所以直接 把下面复制进去保存就行"liveSassCompile.settings.autoprefix&qu…

产业园区数字孪生3d可视化全景展示方案

随着数字经济的发展&#xff0c;数字技术给企业发展带来了机遇的同时&#xff0c;也为企业管理带来挑战。比如园区运维&#xff0c;不仅体量大&#xff0c;复杂的运维管理系统&#xff0c;落地难度也较高。那么如何通过数字化手段重塑园区运营&#xff0c;打通园区各业务数据孤…

关闭浏览器窗口弹出提示框(vue项目)

<script> export default {name: App,mounted() { //开发环境不需要提示if (process.env.NODE_ENV development) returnthis.$nextTick(() > {window.addEventListener(beforeunload, this.beforeUnload)})},beforeDestroy() {if (process.env.NODE_ENV development…

生成式AI系列 —— DCGAN生成手写数字

1、模型构建 1.1 构建生成器 # 导入软件包 import torch import torch.nn as nnclass Generator(nn.Module):def __init__(self, z_dim20, image_size256):super(Generator, self).__init__()self.layer1 nn.Sequential(nn.ConvTranspose2d(z_dim, image_size * 32,kernel_s…

「Vue|网页开发|前端开发」01 快速入门:用vue-cli快速写一个Vue的HelloWorld项目

本文主要介绍如何用vue开发的标准化工具vue-cli快速搭建一个符合实际业务项目结构的hello world网页项目并理解vue的代码文件结构以及页面渲染流程。 文章目录 一、准备工作&#xff1a;安装node.js二、项目搭建创建项目目录全局安装vue-cli使用Webpack初始化项目启动项目学会…

SpringBoot---内置Tomcat 配置和切换

&#x1f600;前言 本篇博文是关于内置Tomcat 配置和切换&#xff0c;希望你能够喜欢 &#x1f3e0;个人主页&#xff1a;晨犀主页 &#x1f9d1;个人简介&#xff1a;大家好&#xff0c;我是晨犀&#xff0c;希望我的文章可以帮助到大家&#xff0c;您的满意是我的动力&#x…

SVM详解

公式太多了&#xff0c;就用图片用笔记呈现&#xff0c;SVM虽然算法本质一目了然&#xff0c;但其中用到的数学推导还是挺多的&#xff0c;其中拉格朗日约束关于α>0这块证明我看了很长时间&#xff0c;到底是因为悟性不够。对偶问题也是&#xff0c;用了一个简单的例子才明…

React请求机制优化思路 | 京东云技术团队

说起数据加载的机制&#xff0c;有一个绕不开的话题就是前端性能&#xff0c;很多电商门户的首页其实都会做一些垂直的定制优化&#xff0c;比如让请求在页面最早加载&#xff0c;或者在前一个页面就进行预加载等等。随着react18的发布&#xff0c;请求机制这一块也是被不断谈起…

3 个 ChatGPT 插件您需要立即下载3 ChatGPT Extensions You need to Download Immediately

在16世纪&#xff0c;西班牙探险家皮萨罗带领约200名西班牙士兵和37匹马进入了印加帝国。尽管印加帝国的军队数量达到了数万&#xff0c;其中包括5,000名精锐步兵和3,000名弓箭手&#xff0c;他们装备有大刀、长矛和弓箭等传统武器。但皮萨罗的军队中有100名火枪手&#xff0c;…

eDP接口的PCB布局布线要求

eDP接口是一种基于DisplayPort架构和协议的一种全数字化接口&#xff0c;传递高分辨率信号只需要较简单的连接器以及较少的引脚就可以实现&#xff0c;同时还能够实现多数据同时传输。 图1 EDP接口 eDP接口的PCB设计布局布线注意事项&#xff1a; 1、远离干扰源&#xff0c;防…

数据分析15——office中的Excel基础技术汇总

0、前言&#xff1a; 这部分总结就是总结每个基础技术的定义&#xff0c;在了解基础技术名称和定义后&#xff0c;方便对相关技术进行检索学习。笔记不会详细到所有操作都说明&#xff0c;但会把基础操作的名称及作用说明&#xff0c;可自行检索。本文对于大部分读者有以下作用…

html动态爱心代码【一】(附源码)

前言 七夕马上就要到了&#xff0c;为了帮助大家高效表白&#xff0c;下面再给大家带来了实用的HTML浪漫表白代码(附源码)背景音乐&#xff0c;可用于520&#xff0c;情人节&#xff0c;生日&#xff0c;表白等场景&#xff0c;可直接使用。 效果演示 文案修改 var loverNam…

windows下, artemis学习

1. download artemis from apache ActiveMQhttps://activemq.apache.org/components/artemis/download/2. 解压缩到 C:/software/apache-artemis-2.30.0/ 2. 进入到cmd&#xff0c; 执行 C:\software\apache-artemis-2.30.0\bin>artemis create C:/software/apache-artem…

数据结构—树表的查找

7.3树表的查找 ​ 当表插入、删除操作频繁时&#xff0c;为维护表的有序表&#xff0c;需要移动表中很多记录。 ​ 改用动态查找表——几种特殊的树 ​ 表结构在查找过程中动态生成 ​ 对于给定值key ​ 若表中存在&#xff0c;则成功返回&#xff1b; ​ 否则&#xff0…

[C++ 网络协议编程] 域名及网络地址

1. DNS服务器 DNS&#xff08;Domain Name System&#xff09;&#xff1a;是对IP地址和域名&#xff08;如:www.baidu.com等&#xff09;进行相互转换的系统&#xff0c;其核心是DNS服务器。 我们输入的www.baidu.com是域名&#xff0c;是一种虚拟地址&#xff0c;而非实际地…

JVM详解

文章目录 一、JVM 执行流程二、类加载三、双亲委派模型四、垃圾回收机制&#xff08;GC&#xff09; 一、JVM 执行流程 程序在执行之前先要把java代码转换成字节码&#xff08;class文件&#xff09;&#xff0c;JVM 首先需要把字节码通过一定的方式 类加载器&#xff08;Clas…

【nodejs】用Node.js实现简单的壁纸网站爬虫

1. 简介 在这个博客中&#xff0c;我们将学习如何使用Node.js编写一个简单的爬虫来从壁纸网站获取图片并将其下载到本地。我们将使用Axios和Cheerio库来处理HTTP请求和HTML解析。 2. 设置项目 首先&#xff0c;确保你已经安装了Node.js环境。然后&#xff0c;我们将创建一个…

【前端vue升级】vue2+js+elementUI升级为vue3+ts+elementUI plus

一、工具的选择 近期想将vuejselementUI的项目升级为vue3tselementUI plus&#xff0c;以获得更好的开发体验&#xff0c;并且vue3也显著提高了性能&#xff0c;所以在此记录一下升级的过程对于一个正在使用的项目手工替换肯定不是个可实现的解决方案&#xff0c;更优方案是基于…