Introducción a la herramienta Apache BeanUtils

beanutils, como sugiere el nombre, es una clase de herramienta para java beans, que puede ayudarnos a leer (obtener) y establecer (establecer) valores de propiedad de bean fácilmente, definir dinámicamente y acceder a propiedades de bean; si tiene cuidado, encontrará que JDK ha proporcionado un paquete java .beans también puede lograr las funciones anteriores, pero es más problemático de usar, por lo que nació apache commons beanutils, puede ver en el código fuente que, de hecho, apache commons beanutils se implementa en base a java Paquete .beans de jdk.

experto:

<dependency>
        <groupId>commons-chain</groupId>
        <artifactId>commons-chain</artifactId>
        <version>1.2</version>
</dependency>

El paquete commons-chain tiene principalmente las siguientes tres clases de herramientas: BeanUtils, PropertyUtils, ConvertUtils

1. Establecer y acceder a las propiedades del Bean

1.1) Los Javabeans generalmente tienen las siguientes características:

1) La clase debe tener derechos de acceso público y debe tener un método de construcción público sin argumentos . La razón de esto es principalmente para facilitar el uso de la reflexión de Java para crear dinámicamente instancias de objetos:

Clase beanClass = Class.forName(className);

Objeto beanInstance = beanClass.newInstance();

2) Dado que el método de construcción de javabean no tiene parámetros, la configuración del comportamiento de nuestro bean (es decir, establecer el valor de la propiedad del bean) no se puede completar en el método de construcción, y el valor de la propiedad debe establecerse mediante el método set. El método de establecimiento aquí se nombrará de acuerdo con una determinada convención, como setHireDate, setName. . .

3) La convención de nomenclatura para leer y configurar los valores de las propiedades del bean, es decir, el método getter y el método setter, pero aquí se debe prestar especial atención a la convención de tipo booleano, como se muestra en el siguiente ejemplo:

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) No es necesario proporcionar métodos setter y getter para cada atributo. Solo podemos definir un método getter para un atributo sin definir un método setter. Dichos atributos generalmente son atributos de solo lectura;

1.2) Combate real

Las propiedades de Bean se pueden configurar y obtener a través de BeanUtils y PropertyUtils.

1) PropertyUtils establece y obtiene propiedades:

  • Tipos de datos básicos:
    • PropertyUtils.getSimpleProperty(Objeto, Cadena)
    • PropertyUtils.setSimpleProperty(Objeto, Cadena, Objeto)
  • Tipo de índice:
    • PropertyUtils.getIndexedProperty (Objeto, Cadena)
    • PropertyUtils.getIndexedProperty (Objeto, Cadena, int)
    • PropertyUtils.setIndexedProperty(Objeto, Cadena, Objeto)
    • PropertyUtils.setIndexedProperty(Objeto, Cadena, int, Objeto)
  • Tipo de mapa:
    • PropertyUtils.getMappedProperty(Objeto, Cadena)
    • PropertyUtils.getMappedProperty (Objeto, Cadena, Cadena)
    • PropertyUtils.setMappedProperty(Objeto, Cadena, Objeto)
    • PropertyUtils.setMappedProperty(Objeto, Cadena, Cadena, Objeto)
  • tipo anidado:
    • PropertyUtils.getNestedProperty (Objeto, Cadena)
    • PropertyUtils.setNestedProperty(Objeto, Cadena, Objeto)
  • Tipo genérico:
    • PropertyUtils.getProperty (Objeto, Cadena)
    • PropertyUtils.setProperty(Objeto, Cadena, Objeto)

Ejemplo:

//定义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);

Lo anterior también se puede utilizar de la siguiente manera:

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 establece y obtiene propiedades:

BeanUtils solo tiene los dos métodos siguientes para configurar y obtener propiedades

  • BeanUtils.getProperty (Objeto, Cadena)
  • BeanUtils.setProperty (Objeto, Cadena, Objeto)

 Ejemplo:

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. Copia las propiedades del Bean.

2.1) BeanUtils tiene los dos métodos siguientes:

  • poblar: copie el valor del par clave-valor en el mapa al valor de propiedad del bean;
  • copyProperties: copia las propiedades de un bean a otro, preste atención a la copia superficial

Nota: La diferencia entre poblar y copiarProperties es que para los tipos Integer, Float y Boolean, el primero (rellenar) para valores nulos se convertirá en el valor predeterminado después de copiarse en las propiedades del Bean.

1) poblar:

//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)

ilustrar:

  • Para los tipos entero, flotante y booleano, si es nulo, se convertirá en el valor predeterminado (0, 0,1, falso) después de convertirse en la propiedad del bean.
  • Para el tipo de fecha, si es nulo u otro tipo, se informará un error cuando se convierta en un bean y se deberá usar ConvertUtils para la conversión de tipos (ver más abajo)
  • Conversión de tipos de soporte: como entre Integer y String

2)copiarPropiedades:

Hay otro objeto (tipo diferente al Empleado)

@Data
public class Employee2 {
	private Integer id;
	private String name;
	private String isGood;
	private String score;
	private String createTime;
	private Float f1;
}

prueba

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)
}

ilustrar:

  • Para los tipos Integer, Float, Boolean y Date, si es nulo, también será nulo después de copiar
  • Admite conversión de tipos: siempre que dos beans tengan el mismo nombre de propiedad, el tipo se puede convertir y copiar. Por ejemplo, convierta tipos enteros, flotantes y booleanos a cadenas

2.2) PropertyUtils para copia de propiedad:

1) Diferencias con BeanUtils:

  • PropertyUtils solo admite la copia de propiedades entre dos beans, no Map to Bean
  • Cuando PropertyUtils copia propiedades entre dos beans, debe asegurarse de que los nombres y tipos sean los mismos ; de lo contrario, se informará un error. Cuando BeanUtils copia propiedades, los nombres son los mismos y los tipos se pueden convertir.

 

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); //报错

Mensaje de error:

 

2) Descripción:

  • PropertyUtils no admite la conversión de tipos.
  • Para valores nulos, PropertyUtils también es nulo después de copiar

3. Conversión de tipo personalizado ConvertUtils

1) Convertidor de fecha:

DateConverter hereda DateTimeConverter, que es la conversión de tipo de hora que viene con el paquete beanutils, que incluye:

ejemplo

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) Personalizar: 

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

Nota: Para setProperty, si hay un tipo de hora, se requiere un convertidor personalizado.

Supongo que te gusta

Origin blog.csdn.net/liuxiao723846/article/details/132422611
Recomendado
Clasificación