Introdução à ferramenta Apache BeanUtils

beanutils, como o nome sugere, é uma classe de ferramenta para java beans, que pode nos ajudar a ler (obter) e definir (definir) facilmente valores de propriedades de bean, definir dinamicamente e acessar propriedades de bean; se você for cuidadoso, descobrirá que JDK forneceu um pacote java .beans também pode realizar as funções acima, mas é mais problemático de usar, então o apache commons beanutils nasceu; você pode ver no código-fonte que, na verdade, o apache commons beanutils é implementado com base no java Pacote .beans do jdk.

especialista:

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

O pacote commons-chain possui principalmente as seguintes três classes de ferramentas: BeanUtils, PropertyUtils, ConvertUtils

1. Defina e acesse as propriedades do Bean

1.1) Javabeans geralmente possuem as seguintes características:

1) A classe deve ter direitos de acesso público e um método de construção público sem argumentos . A razão para isso é principalmente para facilitar o uso da reflexão Java para criar instâncias de objetos dinamicamente:

Classe beanClass = Class.forName(className);

Objeto beanInstance = beanClass.newInstance();

2) Como o método de construção do javabean não possui parâmetros, a configuração do comportamento do nosso bean (ou seja, definir o valor da propriedade do bean) não pode ser concluída no método de construção, e o valor da propriedade deve ser definido através do método set. O método setter aqui será nomeado de acordo com uma determinada convenção, como setHireDate, setName. . .

3) A convenção de nomenclatura para leitura e definição de valores de propriedades do bean, ou seja, o método getter e o método setter, mas aqui você precisa prestar atenção especial à convenção do tipo booleano, conforme mostrado no exemplo a seguir:

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) Não é necessário fornecer métodos setter e getter para cada atributo. Só podemos definir um método getter para um atributo sem definir um método setter. Tais atributos são geralmente atributos somente leitura;

1.2) Combate real

As propriedades do bean podem ser definidas e obtidas por meio de BeanUtils e PropertyUtils.

1) PropertyUtils define e obtém propriedades:

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

Exemplo:

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

O acima também pode ser usado da seguinte maneira:

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 define e obtém propriedades:

BeanUtils possui apenas os dois métodos a seguir para definir e obter propriedades

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

 Exemplo:

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. Copie as propriedades do Bean

2.1) BeanUtils possui os dois métodos a seguir:

  • populate: copia o valor do par chave-valor no Mapa para o valor da propriedade do bean;
  • copyProperties: Copie as propriedades de um bean para outro bean, preste atenção na cópia superficial

Nota: A diferença entre populate e copyProperties é que para os tipos Integer, Float e Boolean, o primeiro (populate) para valores nulos se tornará o valor padrão após ser copiado para as propriedades do Bean.

1)preencher:

//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 os tipos Integer, Float e Boolean, se for nulo, se tornará o valor padrão (0, 0,1, false) após ser convertido na propriedade do bean
  • Para o tipo Date, se for null ou outros tipos, um erro será relatado quando for convertido em um bean, e ConvertUtils precisa ser usado para conversão de tipo (veja abaixo)
  • Conversão de tipo de suporte: como entre Inteiro e String

2)copiarPropriedades:

Existe outro objeto (tipo diferente de Funcionário)

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

teste

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 os tipos Integer, Float, Boolean e Date, se for nulo, também será nulo após a cópia
  • Suporte à conversão de tipo: desde que dois beans tenham o mesmo nome de propriedade, o tipo pode ser convertido e copiado. Por exemplo, converta os tipos Integer, Float e Boolean em String

2.2) PropertyUtils para cópia de propriedade:

1) Diferenças do BeanUtils:

  • PropertyUtils suporta apenas cópia de propriedades entre dois beans, não Map to Bean
  • Quando PropertyUtils copia propriedades entre dois beans, ele deve garantir que os nomes e tipos sejam iguais , caso contrário, um erro será relatado. Quando BeanUtils copia propriedades, os nomes são os mesmos e os tipos podem ser convertidos.

 

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

Mensagem de erro:

 

2) Descrição:

  • PropertyUtils não oferece suporte à conversão de tipo.
  • Para valores nulos, PropertyUtils também é nulo após a cópia

3. Conversão de tipo personalizado ConvertUtils

1)Conversor de data:

DateConverter herda DateTimeConverter, que é a conversão do tipo de hora que vem com o pacote beanutils, incluindo:

exemplo

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, se houver um tipo de hora, será necessário um conversor personalizado.

Acho que você gosta

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