beanutils は、その名前が示すように、Java Bean のツール クラスであり、Bean プロパティ値の読み取り (取得) と設定 (設定)、Bean プロパティの動的定義とアクセスを簡単に行うことができます。注意していれば、JDK が.beans パッケージでも上記の機能を実現できますが、使用するのが面倒なので、Apache Commons beanutils が誕生しました; 実際には、Apache Commons beanutils は Java をベースに実装されていることがソース コードからわかります。 jdk の .beans パッケージ。
メイブン:
<dependency>
<groupId>commons-chain</groupId>
<artifactId>commons-chain</artifactId>
<version>1.2</version>
</dependency>
commons-chain パッケージには主に、BeanUtils、PropertyUtils、ConvertUtils の 3 つのツール クラスがあります。
1. Bean プロパティの設定とアクセス
1.1) Javabean には一般に次の特徴があります。
1) クラスにはパブリック アクセス権が必要で、パブリックな引数なしの構築メソッドが必要です。この理由は主に、オブジェクト インスタンスを動的に作成する Java リフレクションの使用を容易にするためです。
クラス beanClass = Class.forName(className);
オブジェクト beanInstance = beanClass.newInstance();
2) Javabean の構築メソッドにはパラメータがないため、Bean の動作設定 (つまり、Bean のプロパティ値の設定) を構築メソッド内で完了することができず、set メソッドを通じてプロパティ値を設定する必要があります。ここでのセッター メソッドには、setHireDate、setName などの特定の規則に従って名前が付けられます。。。
3) Bean プロパティ値の読み取りと設定の命名規則、つまりゲッター メソッドとセッター メソッド。ただし、ここでは、次の例に示すように、ブール型の規則に特別な注意を払う必要があります。
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) 各属性にセッター メソッドとゲッター メソッドを提供する必要はありません。セッター メソッドを定義せずに、属性のゲッター メソッドのみを定義できます。このような属性は通常、読み取り専用の属性です。
1.2) 実戦
Bean プロパティは、BeanUtils および PropertyUtils を通じて設定および取得できます。
1) PropertyUtils はプロパティを設定および取得します。
- 基本的なデータ型:
- PropertyUtils.getSimpleProperty(オブジェクト, 文字列)
- PropertyUtils.setSimpleProperty(オブジェクト, 文字列, オブジェクト)
- インデックスの種類:
- PropertyUtils.getIndexedProperty(オブジェクト, 文字列)
-
- PropertyUtils.getIndexedProperty(Object, String, int)
- PropertyUtils.setIndexedProperty(オブジェクト, 文字列, オブジェクト)
- PropertyUtils.setIndexedProperty(Object, String, int, Object)
- マップの種類:
- PropertyUtils.getMappedProperty(オブジェクト, 文字列)
-
- PropertyUtils.getMappedProperty(オブジェクト, 文字列, 文字列)
- PropertyUtils.setMappedProperty(オブジェクト, 文字列, オブジェクト)
- PropertyUtils.setMappedProperty(オブジェクト, 文字列, 文字列, オブジェクト)
- ネストされた型:
- PropertyUtils.getNestedProperty(オブジェクト, 文字列)
- PropertyUtils.setNestedProperty(オブジェクト, 文字列, オブジェクト)
- 汎用タイプ:
- PropertyUtils.getProperty(オブジェクト, 文字列)
- PropertyUtils.setProperty(オブジェクト, 文字列, オブジェクト)
例:
//定义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 にはプロパティを設定および取得するメソッドが次の 2 つしかありません
- BeanUtils.getProperty(オブジェクト, 文字列)
- BeanUtils.setProperty(オブジェクト, 文字列, オブジェクト)
例:
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 には次の 2 つのメソッドがあります。
- Populate: マップ内のキーと値のペアの値を Bean のプロパティ値にコピーします。
- copyProperties: ある Bean のプロパティを別の Bean にコピーします。浅いコピーに注意してください。
注: Populate と copyProperties の違いは、Integer、Float、Boolean 型の場合、null 値の前者 (populate) が Bean のプロパティにコピーされた後のデフォルト値になることです。
1)人口:
//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)コピープロパティ:
別のオブジェクトがあります (従業員とは異なるタイプ)
@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 になります。
- 型変換のサポート: 2 つの Bean のプロパティ名が同じである限り、型を変換してコピーできます。たとえば、Integer、Float、Boolean 型を String に変換します。
2.2) プロパティ コピー用の PropertyUtils:
1) BeanUtils との違い:
- PropertyUtils は 2 つの Bean 間のプロパティのコピーのみをサポートし、Bean へのマップはサポートしません。
- PropertyUtils が 2 つの 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 は、Beanutils パッケージに付属する時刻型変換である DateTimeConverter を継承します。次のものが含まれます。
例
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 の場合、時刻型がある場合は、カスタム コンバーターが必要です。