org.springframework.beans.BeanUtils與org.apache.commons.beanutils.BeanUtils的copyProperties用法區別

知識點

org.springframework.beans.BeanUtils與org.apache.commons.beanutils.BeanUtils都提供了copyProperties方法,做用是將一個Bean對象中的數據封裝到另外一個屬性結構類似的Bean對象中java

1)二者的copyProperties方法參數位置不一樣spring

  org.springframework.beans.BeanUtils:  copyProperties(sourceDemo, targetDemo)sql

  org.apache.commons.beanutils.BeanUtils:  copyProperties(targetDemo, sourceDemo)apache

2)要求兩個Bean的屬性名相同,且有對應的setXxx方法和getXxx方法。其實底層原理是使用sourceDemo的getXxx方法和targetDemo的setXxx方法app

3)sourceDemo有的屬性而targetDemo沒有的屬性,不會封裝到targetDemo對象中;ide

   targetDemo有的屬性而sourceDemo沒有的屬性,會封裝到targetDemo中,數據爲默認值(注意基本類型默認值與引用類型默認值不一樣)測試

4)類型轉換問題ui

  a)基本類型與其對應的封裝類型能夠相互轉換this

  b)org.springframework.beans.BeanUtils與org.apache.commons.beanutils.BeanUtils對於String和Date類型轉換的狀況是不一樣的,具體看如下案例spa

 

案例一

SourceDemo

package com.fortis.customer.test;

import java.util.Date;

import org.apache.commons.lang3.builder.ToStringBuilder;

public class SourceDemo {
    
    private int id;
    
    private String name;
    
    private String address;
    
    private Date createTime;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this);
    }
    
}

 

TargetDemo

package com.fortis.customer.test;

import java.util.Date;

import org.apache.commons.lang3.builder.ToStringBuilder;

public class TargetDemo {
    
    private Integer id;
    
    private String name;
    
    private String email;
    
    private Date createTime;
    
    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }
    
    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this);
    }
    
}

 

Test

package com.fortis.customer.test;

import java.lang.reflect.InvocationTargetException;
import java.util.Date; public class Test {

    public static void main(String[] args) throws IllegalAccessException, InvocationTargetException {
        
        SourceDemo sourceDemo = new SourceDemo();
        sourceDemo.setId(10);
        sourceDemo.setName("姓名");
        sourceDemo.setAddress("地址");
        sourceDemo.setCreateTime(new Date());
        
        TargetDemo targetDemo = new TargetDemo();
        org.springframework.beans.BeanUtils.copyProperties(sourceDemo, targetDemo);
        System.out.println(targetDemo);
        
        org.apache.commons.beanutils.BeanUtils.copyProperties(targetDemo, sourceDemo);
        System.out.println(targetDemo);
    }
}

 

測試效果:

[id=10,name=姓名,email=<null>,createTime=Fri Jun 30 16:19:31 CST 2017]
[id=10,name=姓名,email=<null>,createTime=Fri Jun 30 16:19:31 CST 2017]

結論:基本類型與其對應的封裝類型是能夠相互轉換的

 

案例二

SourceDemo

package com.fortis.customer.test;

import java.util.Date;

import org.apache.commons.lang3.builder.ToStringBuilder;

public class SourceDemo {
    
    private int id;
    
    private String name;
    
    private String address;
    
    private Date createTime;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this);
    }
    
}

 

TargetDemo

package com.fortis.customer.test;

import org.apache.commons.lang3.builder.ToStringBuilder;

public class TargetDemo {
    
    private Integer id;
    
    private String name;
    
    private String email;
    
    private String createTime;
    
    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getCreateTime() {
        return createTime;
    }

    public void setCreateTime(String createTime) {
        this.createTime = createTime;
    }
    
    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this);
    }
    
}

 

Test

package com.fortis.customer.test;

import java.lang.reflect.InvocationTargetException;
import java.util.Date; public class Test {

    public static void main(String[] args) throws IllegalAccessException, InvocationTargetException {
        
        SourceDemo sourceDemo = new SourceDemo();
        sourceDemo.setId(10);
        sourceDemo.setName("姓名");
        sourceDemo.setAddress("地址");
        sourceDemo.setCreateTime(new Date(0));
        
        TargetDemo targetDemo = new TargetDemo();
        org.springframework.beans.BeanUtils.copyProperties(sourceDemo, targetDemo);
        System.out.println(targetDemo);
        
        //org.apache.commons.beanutils.BeanUtils.copyProperties(targetDemo, sourceDemo);
        //System.out.println(targetDemo);
    }
}

 

測試效果:

Exception in thread "main" org.springframework.beans.FatalBeanException: Could not copy properties from source to target; nested exception is java.lang.IllegalArgumentException: argument type mismatch
    at org.springframework.beans.BeanUtils.copyProperties(BeanUtils.java:599)
    at org.springframework.beans.BeanUtils.copyProperties(BeanUtils.java:509)
    at com.fortis.customer.test.Test.main(Test.java:17)
Caused by: java.lang.IllegalArgumentException: argument type mismatch
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.springframework.beans.BeanUtils.copyProperties(BeanUtils.java:596)
    ... 2 more

結論:org.springframework.beans.BeanUtils.copyProperties不能夠將java.util.Date類型轉換成String類型

同時:也不可將java.sql.Date類型轉換成String類型(由於網上搜的說能夠支持java.sql.Date類型,我本身測試了一下發現不能夠,仍是信本身靠譜)

Exception in thread "main" org.springframework.beans.FatalBeanException: Could not copy properties from source to target; nested exception is java.lang.IllegalArgumentException: argument type mismatch
    at org.springframework.beans.BeanUtils.copyProperties(BeanUtils.java:599)
    at org.springframework.beans.BeanUtils.copyProperties(BeanUtils.java:509)
    at com.fortis.customer.test.Test.main(Test.java:17)
Caused by: java.lang.IllegalArgumentException: argument type mismatch
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.springframework.beans.BeanUtils.copyProperties(BeanUtils.java:596)
    ... 2 more

 

案例三

Test

package com.fortis.customer.test;

import java.lang.reflect.InvocationTargetException;
import java.util.Date; public class Test {

    public static void main(String[] args) throws IllegalAccessException, InvocationTargetException {
        
        SourceDemo sourceDemo = new SourceDemo();
        sourceDemo.setId(10);
        sourceDemo.setName("姓名");
        sourceDemo.setAddress("地址");
        sourceDemo.setCreateTime(new Date(0));
        
        TargetDemo targetDemo = new TargetDemo();
        //org.springframework.beans.BeanUtils.copyProperties(sourceDemo, targetDemo);
        //System.out.println(targetDemo);
        
        org.apache.commons.beanutils.BeanUtils.copyProperties(targetDemo, sourceDemo);
        System.out.println(targetDemo);
    }
}

注:SourceDemo和TargetDemo與案例二相同

 

測試效果:java.util.Date

[id=10,name=姓名,email=<null>,createTime=Thu Jan 01 08:00:00 CST 1970]

結論:org.apache.commons.beanutils.BeanUtils.copyProperties能夠將java.util.Date類型轉換成String類型

 

測試效果:java.sql.Date

[id=10,name=姓名,email=<null>,createTime=1970-01-01]

結論:org.apache.commons.beanutils.BeanUtils.copyProperties能夠將java.sql.Date類型轉換成String類型

注意:雖然均可以轉換,但發現二者的日期格式仍是不一樣的

 

案例四:

SourceDemo

package com.fortis.customer.test;

import org.apache.commons.lang3.builder.ToStringBuilder;

public class SourceDemo {
    
    private int id;
    
    private String name;
    
    private String address;
    
    private String createTime;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getCreateTime() {
        return createTime;
    }

    public void setCreateTime(String createTime) {
        this.createTime = createTime;
    }

    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this);
    }
    
}

 

TargetDemo

package com.fortis.customer.test;

import java.util.Date;

import org.apache.commons.lang3.builder.ToStringBuilder;

public class TargetDemo {
    
    private Integer id;
    
    private String name;
    
    private String email;
    
    private Date createTime;
    
    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }
    
    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this);
    }
    
}

 

Test

package com.fortis.customer.test;

import java.lang.reflect.InvocationTargetException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Test {

    public static void main(String[] args) throws IllegalAccessException, InvocationTargetException {
        
        SourceDemo sourceDemo = new SourceDemo();
        sourceDemo.setId(10);
        sourceDemo.setName("姓名");
        sourceDemo.setAddress("地址");
        sourceDemo.setCreateTime(new SimpleDateFormat("yyyyMMddHHmmss").format(new Date(0)));
        
        TargetDemo targetDemo = new TargetDemo();
        org.springframework.beans.BeanUtils.copyProperties(sourceDemo, targetDemo);
        System.out.println(targetDemo);
        
        //org.apache.commons.beanutils.BeanUtils.copyProperties(targetDemo, sourceDemo);
        //System.out.println(targetDemo);
    }
}

測試效果:

Exception in thread "main" org.springframework.beans.FatalBeanException: Could not copy properties from source to target; nested exception is java.lang.IllegalArgumentException: argument type mismatch
    at org.springframework.beans.BeanUtils.copyProperties(BeanUtils.java:599)
    at org.springframework.beans.BeanUtils.copyProperties(BeanUtils.java:509)
    at com.fortis.customer.test.Test.main(Test.java:18)
Caused by: java.lang.IllegalArgumentException: argument type mismatch
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.springframework.beans.BeanUtils.copyProperties(BeanUtils.java:596)
    ... 2 more

結論:org.springframework.beans.BeanUtils.copyProperties不能夠將String類型轉換成java.util.Date類型

同時:也不可將String類型轉換成java.sql.Date類型

 

案例五

Test

package com.fortis.customer.test;

import java.lang.reflect.InvocationTargetException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Test { public static void main(String[] args) throws IllegalAccessException, InvocationTargetException { SourceDemo sourceDemo = new SourceDemo(); sourceDemo.setId(10); sourceDemo.setName("姓名"); sourceDemo.setAddress("地址"); sourceDemo.setCreateTime(new SimpleDateFormat("yyyyMMddHHmmss").format(new Date(0))); TargetDemo targetDemo = new TargetDemo(); //org.springframework.beans.BeanUtils.copyProperties(sourceDemo, targetDemo); //System.out.println(targetDemo);  org.apache.commons.beanutils.BeanUtils.copyProperties(targetDemo, sourceDemo); System.out.println(targetDemo); } }

 

測試效果:java.util.Date

log4j:WARN No appenders could be found for logger (org.apache.commons.beanutils.converters.BooleanConverter).
log4j:WARN Please initialize the log4j system properly.
Exception in thread "main" org.apache.commons.beanutils.ConversionException: DateConverter does not support default String to 'Date' conversion.
    at org.apache.commons.beanutils.converters.DateTimeConverter.toDate(DateTimeConverter.java:468)
    at org.apache.commons.beanutils.converters.DateTimeConverter.convertToType(DateTimeConverter.java:343)
    at org.apache.commons.beanutils.converters.AbstractConverter.convert(AbstractConverter.java:156)
    at org.apache.commons.beanutils.converters.ConverterFacade.convert(ConverterFacade.java:60)
    at org.apache.commons.beanutils.BeanUtilsBean.convert(BeanUtilsBean.java:1078)
    at org.apache.commons.beanutils.BeanUtilsBean.copyProperty(BeanUtilsBean.java:437)
    at org.apache.commons.beanutils.BeanUtilsBean.copyProperties(BeanUtilsBean.java:286)
    at org.apache.commons.beanutils.BeanUtils.copyProperties(BeanUtils.java:137)
    at com.fortis.customer.test.Test.main(Test.java:21)

結論:org.apache.commons.beanutils.BeanUtils

看錯誤日誌,發現說是默認的轉換器是不能夠將String類型轉換成java.util.Date,可能本身配置一個轉換器就能夠轉了吧,我沒有測試過

 

測試效果:java.sql.Date

log4j:WARN No appenders could be found for logger (org.apache.commons.beanutils.converters.BooleanConverter).
log4j:WARN Please initialize the log4j system properly.
Exception in thread "main" org.apache.commons.beanutils.ConversionException: String must be in JDBC format [yyyy-MM-dd] to create a java.sql.Date
    at org.apache.commons.beanutils.converters.DateTimeConverter.toDate(DateTimeConverter.java:436)
    at org.apache.commons.beanutils.converters.DateTimeConverter.convertToType(DateTimeConverter.java:343)
    at org.apache.commons.beanutils.converters.AbstractConverter.convert(AbstractConverter.java:156)
    at org.apache.commons.beanutils.converters.ConverterFacade.convert(ConverterFacade.java:60)
    at org.apache.commons.beanutils.BeanUtilsBean.convert(BeanUtilsBean.java:1078)
    at org.apache.commons.beanutils.BeanUtilsBean.copyProperty(BeanUtilsBean.java:437)
    at org.apache.commons.beanutils.BeanUtilsBean.copyProperties(BeanUtilsBean.java:286)
    at org.apache.commons.beanutils.BeanUtils.copyProperties(BeanUtils.java:137)
    at com.fortis.customer.test.Test.main(Test.java:21)

結論:org.apache.commons.beanutils.BeanUtils

看錯誤日誌,發現說是須要將String類型轉成java.sql.Date,使用simpleDateFormat是將String類型轉成java.util.Date,可能轉成java.sql.Date就能夠了吧,我沒測試過

 注意:我這裏說的轉換,單純是指這一行代碼sourceDemo.setCreateTime(new SimpleDateFormat("yyyyMMddHHmmss").format(new Date(0)));而不是兩個Bean的類型轉換

 

總之,不管是org.springframework.beans.BeanUtils仍是org.apache.commons.beanutils.BeanUtils,默認狀況下都不能將String類型轉成Date類型

 

案例六:

SourceDemo:

  private String name;

TargetDemo:

  private String name = 「馬超」;

  private String email = "張飛";

複製以後的結果:name = null,email = 「張飛」

 

SourceDemo:

  private String name = 「諸葛亮」;

TargetDemo:

  private String name = 「馬超」;

  private String email = "張飛";

複製以後的結果:name = 「諸葛亮」,email = 「張飛」

注:使用兩種BeanUtils效果相同

相關文章
相關標籤/搜索