CustomPropertyEditor

Let’s look at how the custom property editor do the job for us. Before that I’ll first demo if we didn’t use PropertyEditor, Spring will not understand what exactly the type and how can convert. Therefore exception are throw.

public class Holiday {

    private String id;

    private Calendar holiday;

    public Holiday() {
        //empty constructor		
    }

    public String getId() {
        return id;
    }

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

    public Calendar getHoliday() {
        return holiday;
    }

    public void setHoliday(Calendar holiday) {
        this.holiday = holiday;
    }

}

PropertyEditorTest

public class PropertyEditorTest {
	
    private Calendar todayHoliday;

    public static void main(String[] args) {

        GenericXmlApplicationContext ctx = new GenericXmlApplicationContext();
	ctx.load("classpath:/test-applicationcontext.xml");
	ctx.refresh();
		
	Holiday holiday = ctx.getBean(Holiday.class);
		
	PropertyEditorTest test = new PropertyEditorTest();
	test.todayHoliday = holiday.getHoliday();
	System.out.println(test.todayHoliday.get(Calendar.MONDAY));
	System.out.println(test.todayHoliday.get(Calendar.DAY_OF_MONTH));
	System.out.println(test.todayHoliday.get(Calendar.YEAR));	
    }

}

ApplicationContext.xml

<bean id="holiday" class="com.eweol.init.Holiday">
	<property name="id">
                 <value>Independent</value>
        </property>
	<property name="holiday">
		<value>31-08-2014</value>
	</property>
</bean>

 

Result

.ConversionNotSupportedException: Failed to convert property value of type ‘java.lang.String’ to required type ‘java.util.Calendar’ for property ‘holiday’; nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type [java.util.Calendar] for property ‘holiday’: no matching editors or conversion strategy found

 

Generally all input from the application context are consider string, spring does not know how to convert from string to calendar.  So we need to provide a property editor to let spring have sufficient information to do the conversion for us.

public class StringToCalenderPropertyEditor extends PropertyEditorSupport {

   private static DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy");
	
   public String getAsText() {
      Calendar value = (Calendar) getValue();
      Date dateTime = new Date(value.getTimeInMillis());
	    
      return (value != null ? formatter.format(dateTime) : "");
   }

   public void setAsText(String text) throws IllegalArgumentException {
	    
      Date date = null;
      try {
	 date = formatter.parse(text);
      } catch (ParseException e) {
	 e.printStackTrace();
	 date = new Date();
      }
	    
      Calendar cal = Calendar.getInstance();
      cal.setTime(date);
      setValue(cal);
   }
}

Modified the applicationContext

<bean id="holiday" class="com.eweol.init.Holiday">
   <property name="id">
      <value>Independent</value>
   </property>
   <property name="holiday">
      <value>31-08-2014</value>
   </property>
</bean>
  	  
<bean id="customEditorConfigurer" 
  class="org.springframework.beans.factory.config.CustomEditorConfigurer">

   <property name="customEditors">
   <map>
       <entry key="java.util.Calendar">
	  <bean class="com.example.StringToCalenderPropertyEditor"/>
       </entry>
   </map>
   </property>
</bean>

Result

7

31

2014

You can find the spring conversion tutorial here

 

Spring version 4.x

Spring 4.x slightly change the behaviour of CustomEditorConfigurer. If you run above code with spring version 4.0 library. You may see the error like this.

BeanCreationException: Error creating bean with name 'customEditorConfigurer' defined in class path resource 
....
TypeMismatchException: Failed to convert property value of type 'java.util.LinkedHashMap' to required type 'java.util.Map' for property 'customEditors';
....

 

In Spring 3.2.x  –  customEditors are Map<String, ?>

3.2

<bean id="customEditorConfigurer" class="org.springframework.beans.factory.config.CustomEditorConfigurer">

   <property name="customEditors">
       <map>
           <entry key="com.octworks.ioc.propertyeditor.Name">
	       <bean class="com.codeomitted.HolidayPropertyEditor"/>
          </entry>
      </map>
   </property>

</bean>

Spring 4.x it change to  Map<Class<?>, Class<? extends PropertyEditor>>, the solution is to remove the inner bean as part of the entry value.

4.0x

 

<bean id="customEditorConfigurer" class="org.springframework.beans.factory.config.CustomEditorConfigurer">

   <property name="customEditors">
      <map>
         <entry key="com.xx.xx.Name" value="com.xx.xx.NameEditor"/>
         <entry key="java.util.Calendar"value="com.xx.xx.HolidayPropertyEditor" />
      </map>
   </property>
</bean>

 

 

Alternative

Alternative we can use custom propertyEditorRegistrar implementation.

Step 1. Create your own registrar, CustomNameEditorRegistrar

public class CustomNameEditorRegistrar implements PropertyEditorRegistrar {

   public void registerCustomEditors(PropertyEditorRegistry registry) {
      registry.registerCustomEditor(Name.class, new NamePropertyEditor());
   }

}

Step 2. Register to customEditorConfigurer

<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
    <property name="propertyEditorRegistrars">
         <list>
              <bean class="com.codeomitted.CustomNameEditorRegistrar"/>
         </list>
     </property>
</bean>

Done

 

 

CustomPropertyEditor

One thought on “CustomPropertyEditor

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.