Ads Top

ConvertUtils : Register custom converters when using BeanUtils Copy Properties

In this post, we will learn how to register custom converters to convert to and from different data types when using Apache commons BeanUtils class copyProperties method to copy properties from source object to the target object. The copyProperties method is a static method of BeanUtils class used to copy properties from one object to another object where the property name is the same in both objects.

When we copy properties from one object to another object, we often need to copy an object whose data type is different as compared to the object in which we want to copy. BeanUtils contains a ConvertUtils utility class which facilitates the data conversion between two different data types.

In this tutorial, we will use the below maven dependency of Apache commons.
 <dependency>  
     <groupId>commons-beanutils</groupId>  
      <artifactId>commons-beanutils</artifactId>  
      <version>1.9.3</version>  
 </dependency>  

Let's say, we have below Customer and User class.
Customer.class
 package com.devtalkers.beanutildemo; 

 public class Customer { 

   private Integer id; 

   private String name; 

   private String dob; 

   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 getDob() { 

     return dob; 

   } 

   public void setDob(String dob) { 

     this.dob = dob; 

   } 

   @Override 

   public String toString() { 

     return "Customer{" + 

         "id=" + id + 

         ", name='" + name + '\'' + 

         ", dob='" + dob + '\'' + 

         '}'; 

   } 

 } 


User.class
 package com.devtalkers.beanutildemo;  
 import java.util.Date;  
 public class User {  
   private Integer id;  
   private String name;  
   private Date dob;  
   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 Date getDob() {  
     return dob;  
   }  
   public void setDob(Date dob) {  
     this.dob = dob;  
   }  
   @Override  
   public String toString() {  
     return "User{" +  
         "id=" + id +  
         ", name='" + name + '\'' +  
         ", dob=" + dob +  
         '}';  
   }  
 }  

Both the User and Customer object have the same properties like id, name, and dob. The only difference is that the dob (Date of Birth) field in Customer class is of type string and the dob field in User class is of type Date object.

Let's create a Customer object with the following data.
     Customer customer = new Customer();  
     customer.setId(1);  
     customer.setName("John");  
     customer.setDob("1989-02-16");  

Now, let's copy customer object properties to the user object using the BeanUtils class copyProperties method.
     User user = new User();  
     BeanUtils.copyProperties(user, customer);  

If you try to run the above code, you will get the following error.

Exception in thread "main" org.apache.commons.beanutils.ConversionException: DateConverter does not support default String to 'Date' conversion.

Since the dob field in Customer class is of type string, it is unable to convert string to Date, as dob field is of type Date in User class.

To resolve the above issue, we can use the ConvertUtils utility class provided by the BeanUtils library to register a custom converter.
     ConvertUtils.register(new Converter() {  
       @Override  
       public Object convert(Class aClass, Object o) {  
         SimpleDateFormat simpleDateFormat = new SimpleDateFormat("YYYY-MM-DD");  
         Date date = null;  
         try {  
           date = simpleDateFormat.parse((String) o);  
   
         } catch (ParseException e) {  
           e.printStackTrace();  
         }  
         return date;  
   
       }  
     }, Date.class);  

In the above code snippet, we have registered a custom converter for the data type Date object. We have used the SimpleDateFormat class to convert the string to Date object and returned it.

Below is the method details for the convert method used above:
<T> T convert(Class<T> type, Object value)
Type Parameters:
T - It is the desired result type after conversion.
Parameters:
type - The type of data to which this value should be converted.
value - It is the input value to be converted.
Returns:
It will return the converted value of type T.
Below is the full working code.
1:  package com.devtalkers.beanutildemo;  
2:  import org.apache.commons.beanutils.BeanUtils;  
3:  import org.apache.commons.beanutils.ConvertUtils;  
4:  import org.apache.commons.beanutils.Converter;  
5:  import java.lang.reflect.InvocationTargetException;  
6:  import java.text.ParseException;  
7:  import java.text.SimpleDateFormat;  
8:  import java.util.Date;  
9:  public class ConvertUtilDemo {  
10:    public static void main(String[] args) throws InvocationTargetException, IllegalAccessException {  
11:      //create the customer object  
12:      Customer customer = new Customer();  
13:      customer.setId(1);  
14:      customer.setName("John");  
15:      customer.setDob("1989-02-16");  
16:      //create the user object  
17:      User user = new User();  
18:      //register a customer converter for type Date object  
19:      ConvertUtils.register(new Converter() {  
20:        @Override  
21:        public Object convert(Class aClass, Object o) {  
22:          SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");  
23:          Date date = null;  
24:          try {  
25:            date = simpleDateFormat.parse((String) o);  
26:          } catch (ParseException e) {  
27:            e.printStackTrace();  
28:          }  
29:          return date;  
30:        }  
31:      }, Date.class);  
32:      //copy the properties from customer to user object  
33:      BeanUtils.copyProperties(user, customer);  
34:      //print the user object to the console  
35:      System.out.println(user);  
36:    }  
37:  }  

When we compile and run the above code, we will get the below output printed out on the console.
 User{id=1, name='John', dob=Thu Feb 16 00:00:00 IST 1989}  
As you can see in the above output we have successfully converted the string date object to java Date object.

Copying properties from one object to another is quite a tedious job. Apache commons Beanutils makes this task easier for us by providing us many utility classes.
In this guide, we have discussed the problems that often occur when we try to copy properties from one object to another using the BeanUtils class copyProperties method. Then finally, we saw, how we can use ConvertUtils to register a custom converter when we need to copy an object whose data type is different from the target object.

No comments:

Powered by Blogger.