Announcement Announcement Module
Collapse
No announcement yet.
PropertyEditor not registering. Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • PropertyEditor not registering.

    I recently converted my java.util.Date fields to Jodatime DateTimes. My PropertyEditor for Dates worked fine. I am registering the new PropertyEditor in the same way, but I am getting an error:

    Failed to convert property value of type [java.lang.String] to required type [org.joda.time.DateTime] for property 'startDate'; nested exception is java.lang.IllegalArgumentException: Cannot convert value of type [java.lang.String] to required type [org.joda.time.DateTime] for property 'startDate': no matching editors or conversion strategy found

    I've done a lot of searching to try to figure this problem out. As best I can tell, I am registering my PropertyEditor correctly:

    Code:
    protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Exception {
      String dateFormat = "MM/dd/yyyy";
      binder.registerCustomEditor(org.joda.time.DateTime.class, new DateTimeEditor(dateFormat,true));
      binder.bind(request);
    }
    Since that looks right, I looked to my PropertyEditor. The only relevant methods are the constructor, and setAsText(). They look correct to me. The PropertyEditor I am using, which I found elsewhere in the forum, is included below.

    Code:
    public class DateTimeEditor extends PropertyEditorSupport {
    // ------------------------------ FIELDS ------------------------------
    
    private final DateTimeFormatter formatter;
    private final boolean allowEmpty;
    
    // --------------------------- CONSTRUCTORS ---------------------------
    
    /**
    * Create a new DateTimeEditor instance, using the given format for
    * parsing and rendering.
    * <p/>
    * The "allowEmpty" parameter states if an empty String should be allowed
    * for parsing, i.e. get interpreted as null value. Otherwise, an
    * IllegalArgumentException gets thrown.
    *
    * @param dateFormat DateFormat to use for parsing and rendering
    * @param allowEmpty if empty strings should be allowed
    */
    public DateTimeEditor( String dateFormat, boolean allowEmpty ) {
    this.formatter = DateTimeFormat.forPattern( dateFormat );
    this.allowEmpty = allowEmpty;
    }
    
    // ------------------------ OVERRIDING METHODS ------------------------
    
    /**
    * Format the YearMonthDay as String, using the specified format.
    *
    * @return DateTime formatted string
    */
    public String getAsText() {
    Date value = ( Date ) getValue();
    return value != null ? new DateTime( value ).toString( formatter ) : "";
    }
    
    /**
    * Parse the value from the given text, using the specified format.
    *
    * @param text
    * @throws IllegalArgumentException
    */
    public void setAsText( String text ) throws IllegalArgumentException {
    	if ( allowEmpty && !StringUtils.hasText( text ) ) {
    		// Treat empty String as null value.
    		setValue( null );
    	} else {
    		setValue( new DateTime( formatter.parseDateTime( text ) ).toDate() );
    	}
    }
    }
    I've been trying to figure this out for several hours now. I would greatly appreciate any guidance in solving this problem.
    Last edited by uaine; Oct 7th, 2008, 06:51 AM.

  • #2
    First off all don't bind yourself! Spring will do the binding, the initBinder method should ONLY be about CONFIGURING the binder NOT binding!!

    You can try and register it explicitly for the 'startData' field by including the field name.

    Code:
    protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Exception {
      String dateFormat = "MM/dd/yyyy";
      binder.registerCustomEditor(org.joda.time.DateTime.class, "startDate", new DateTimeEditor(dateFormat,true));
      //NO BINDING, Spring takes care of that!!!
    }

    Comment


    • #3
      Thanks for the help, Marten. I revised my initBinder() method according to your advice. I still get the same error, though now I am only getting it once instead of twice. I suppose that is because "binder.bind(request)" was causing the property editor to attempt to bind a second time.

      But anyway, still the same problem. Is there any way I can try to isolate where this is breaking down? I'm not sure if the PropertyEditor is actually binding successfully, or if there is an error in the PropertyEditor itself.

      Comment


      • #4
        I figured out the problem. The error message was not very helpful. The PropertyEditor was successfully binding. The problem was in the Date casts, int the PropertyEditor.

        For the benefit of others with the same problem, I'll paste the code below. Please note, that this PropertyEditor reads and displays times in UTC.

        Code:
        import java.beans.PropertyEditorSupport;
        import org.joda.time.format.DateTimeFormat;
        import org.joda.time.DateTime;
        import org.joda.time.DateTimeZone;
        import org.springframework.util.StringUtils;
        
        /**
        * Custom PropertyEditorSupport to convert from String to
        * Date using JODA.
        */
        public class DateTimeEditor extends PropertyEditorSupport {
        	// ------------------------------ FIELDS ------------------------------
        	private final String dateFormat;
        	private final boolean allowEmpty;
        
        	// --------------------------- CONSTRUCTORS ---------------------------
        
        	/**
        	 * Create a new DateTimeEditor instance, using the given format for
        	 * parsing and rendering.
        	 * <p/>
        	 * The "allowEmpty" parameter states if an empty String should be allowed
        	 * for parsing, i.e. get interpreted as null value. Otherwise, an
        	 * IllegalArgumentException gets thrown.
        	 * 
        	 * @param dateFormat DateFormat to use for parsing and rendering
        	 * @param allowEmpty if empty strings should be allowed
        	 */
        	public DateTimeEditor( String dateFormat, boolean allowEmpty ) {
        		this.dateFormat = dateFormat;
        		this.allowEmpty = allowEmpty;
        	}
        
        	// ------------------------ OVERRIDING METHODS ------------------------
        
        	public String getAsText() {
        		if(getValue() == null) return ""; //return null if the property is null
        		DateTime value = (( DateTime ) getValue()).withZone(DateTimeZone.UTC); //if the property is not null, read it as a DateTime
        		return value != null ? value.toString() : "";
        	}
        
        	public void setAsText( String text ) throws IllegalArgumentException {
        		if ( allowEmpty && !StringUtils.hasText( text ) ) {
        			// Treat empty String as null value.
        			setValue( null );
        		} else {
        			DateTime val = DateTimeFormat.forPattern(dateFormat).parseDateTime( text ).withZoneRetainFields(DateTimeZone.UTC); 
        			setValue( val );
        		}
        	}
        }

        Comment

        Working...
        X