Aamir
Aamir

Reputation: 2422

CustomDateEditor not working in Spring 4.1.6

I am using a Date dob; field in my pojo class in spring 4.1.6 using maven below are the files associated with my app.

// this is my pojo class.

package com.aamir;

import java.util.Date;

public class Student {

private String firstName;
private Date dob;

public String getFirstName() {
    return firstName;
}
public void setFirstName(String firstName) {
    this.firstName = firstName;
}
public Date getDob() {
    return dob;
}
public void setDob(Date dob) {
    this.dob = dob;
}


}

// this is my client class

package com.aamir;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class ClientStud1 {

public static void main(String[] args) {

    ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
    Student student = (Student) context.getBean("s1");

    System.out.println(student.getFirstName());
    System.out.println(student.getDob()); 

}

} // and finally this is my beans.xml file

  <?xml version="1.0" encoding="UTF-8"?>
 <beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd">

    <bean id="s1" class="com.aamir.Student">
       <property name="firstName" value="aamir"/>
       <property name="dob" value="12-12-1996"/>
   </bean>

    <bean id="dateEditor" 
               class="org.springframework.beans.propertyeditors.CustomDateEditor">
            <constructor-arg>
                <bean class="java.text.SimpleDateFormat">
                    <constructor-arg value="dd-MM-yyyy"/>
                </bean>
            </constructor-arg>
            <constructor-arg value="true"/>
    </bean>

    <bean  class="org.springframework.beans.factory.config.CustomEditorConfigurer">
       <property name="customEditors">
         <map>
           <entry key="java.util.Date" value-ref="dateEditor"/>
         </map>
       </property>
   </bean>


</beans>

and I get this exception every time I try to run the client

org.springframework.beans.factory.BeanCreationException: Error creating bean     with name 'org.springframework.beans.factory.config.CustomEditorConfigurer#0' defined in class path resource [beans.xml]: 
Initialization of bean failed; nested exception is org.springframework.beans.TypeMismatchException: Failed to convert property value of type 'java.util.LinkedHashMap' to required type 'java.util.Map' for property 'customEditors'; nested exception is java.lang.IllegalArgumentException: Cannot convert value of type [org.springframework.beans.propertyeditors.CustomDateEditor] to required type [java.lang.Class] for property 'customEditors[java.util.Date]': PropertyEditor [org.springframework.beans.propertyeditors.ClassEditor] returned inappropriate value of type [org.springframework.beans.propertyeditors.CustomDateEditor]

Upvotes: 2

Views: 2482

Answers (2)

App Work
App Work

Reputation: 22039

As per the official documentation , the recommended way of registering a PropertyEditor is to create a class that implements propertyEditorRegistrar interface. Each propertyEditorRegistrar can register any number of propertyEditors on a given registry.

Two such implementaions are descibed below:

Approach 1: create a generalized class that implements PropertyEditorRegistrar.

This class can be used for any propertyEditor(s), so you can keep this class in your utils.

Lets name it CustomEditorRegistrar and it looks like this:

public class CustomEditorRegistrar implements PropertyEditorRegistrar
{
    Class<?>        t;
    PropertyEditor  propertyEditor;

    public CustomEditorRegistrar(Class<?> t, PropertyEditor propertyEditor)
    {
        this.t = t;
        this.propertyEditor = propertyEditor;
    }

    @Override
    public void registerCustomEditors(PropertyEditorRegistry registry)
    {
        registry.registerCustomEditor(t, propertyEditor);
    }

}

. The bean definition to register a CustomDateEditor is as below:

    <bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
        <property name="propertyEditorRegistrars">
            <list>
                <bean class="mky.spring.property.editor.date.CustomEditorRegistrar">
                    <constructor-arg index="0">
                        <value type="java.lang.Class">java.util.Date</value>
                    </constructor-arg>
                    <constructor-arg index="1">
                        <bean class="org.springframework.beans.propertyeditors.CustomDateEditor">
                            <constructor-arg index="0">
                                <bean class="java.text.SimpleDateFormat">
                                    <constructor-arg value="dd-MM-yyyy" />
                                </bean>
                            </constructor-arg>
                            <constructor-arg index="1" value="true" />
                        </bean>
                    </constructor-arg>
                </bean>
            </list>
        </property>
    </bean>
    <bean
        name="Customer"
        class="mky.spring.property.editor.date.Customer"
        p:name="Customer 1"
        p:address="CounterHills LA"
        p:deliveryDate="12-11-2016"
        p:issueDate="12-10-2016" />

Sys-out client:

public class TestGenericClient
{
    ApplicationContext  ctx;

    public TestGenericClient()
    {
        ctx = new ClassPathXmlApplicationContext("genericPropertyEditorRegistrar-beans.xml");
    }

    public static void main(String[] args)
    {
        System.out.println(new TestGenericClient().ctx.getBean("Customer"));
    }
}

And the output is this:

Name=Customer 1
 Address=CounterHills LA
 Issue Date=Wed Oct 12 00:00:00 GST 2016
 deliveryDate=Sat Nov 12 00:00:00 GST 2016

Approach2: create a specific propertyEditorRegistrar eg, for Date

public class CustomDateEditorRegistrar implements PropertyEditorRegistrar
{

    @Override
    public void registerCustomEditors(PropertyEditorRegistry registry)
    {
        registry.registerCustomEditor(java.util.Date.class, new CustomDateEditor(new SimpleDateFormat("dd-MM-yyyyy"),true));
    }

}

And the bean declaration for this specific CustomDateEditor is :

<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
        <property name="propertyEditorRegistrars">
            <list>
                <bean class="mky.spring.property.editor.date.CustomDateEditorRegistrar" />

            </list>
        </property>
    </bean>

Sys-out cleint:

public TestDateClient()
    {
        ctx = new ClassPathXmlApplicationContext("datePropertyEditorRegistrar-beans.xml");
    }

    public static void main(String[] args)
    {
        System.out.println(new TestDateClient().ctx.getBean("Customer"));
    }

And the same output :

Name=Customer 1
 Address=CounterHills LA
 Issue Date=Wed Oct 12 00:00:00 GST 2016
 deliveryDate=Sat Nov 12 00:00:00 GST 2016

Upvotes: 1

Jose Luis Martin
Jose Luis Martin

Reputation: 10709

Note that PropertyEditor are stateful, so you should not register instances directly.

  • Register property editor classes via customEditor property
  • Add PropertyEditorRegistrars via propertyEditorRegistrars property in CustomEditorConfigurer

As you want to configure the property editor instance, use property editor registrar instead.

    <bean id="customEditorConfigurer" class="org.springframework.beans.factory.config.CustomEditorConfigurer">
       <property name="propertyEditorRegistrars">
         <list>
           <bean class="org.example.CustomDateEditorRegistrar"/>
         </list>
       </property>
   </bean>

Upvotes: 2

Related Questions