Spring MVC Data Binding and user-friendly error messages

Discussion in 'Java' started by cmilley2000@excite.com, Jun 15, 2006.

  1. Guest

    Dear Spring MVC experts!

    I am using a controller of type AbstractWizardFormController to
    implement a multi-page form entry workflow. This controller operates
    on a session-scoped command object which has a property of type
    java.util.Date. On page 3 of the wizard, the user enters a date into a
    textbox which will be bound to a java.util.Date property of the command
    object.

    In my controller, I am registering a custom editor as follows:

    protected void initBinder(HttpServletRequest request,
    ServletRequestDataBinder binder) throws Exception {
    DateFormat df = new SimpleDateFormat("MM/dd/yyyy");
    CustomDateEditor editor = new CustomDateEditor(df, false);
    binder.registerCustomEditor(Date.class, editor);
    }


    The data binding process is behaving as I would expect. If the user
    types an invalid date into the textbox, then the field cannot be bound
    and the framework adds a FieldError to the Errors object with code
    "typeMismatch". Unfortunately, this FieldError results in a very
    un-user-friendly error message being put on the screen. The text of
    the message is:

    "Failed to convert property value of type [java.lang.String] to
    required type [java.util.Date] for property billDate; nested exception
    is java.lang.IllegalArgumentException: Could not parse date:
    Unparseable date: "xyz" "


    It is not at all clear to me how to transform this ugly error message
    to a user-friendly message. I can think of a number of possible ways
    of doing this, but all seem overly-complex. Is there a standard way to
    map data-binding errors to user-friendly messages? Thanks in advance
    for your help.


    Regards,
    Craig
    , Jun 15, 2006
    #1
    1. Advertising

  2. Guest

    Have the customized typeMismatch message in your message properties
    file that Spring load as messageResource.

    Example:
    # For generic error message on type mismatch Date
    typeMismatch.java.util.Date={0} is an invalid date.

    # For specific error message on perticular form field
    # (e.g. startDt is a form field name)
    typeMismatch.startDt=Start Date is an invalid date.

    Cheers,
    Liu Jian


    wrote:
    > Dear Spring MVC experts!
    >
    > I am using a controller of type AbstractWizardFormController to
    > implement a multi-page form entry workflow. This controller operates
    > on a session-scoped command object which has a property of type
    > java.util.Date. On page 3 of the wizard, the user enters a date into a
    > textbox which will be bound to a java.util.Date property of the command
    > object.
    >
    > In my controller, I am registering a custom editor as follows:
    >
    > protected void initBinder(HttpServletRequest request,
    > ServletRequestDataBinder binder) throws Exception {
    > DateFormat df = new SimpleDateFormat("MM/dd/yyyy");
    > CustomDateEditor editor = new CustomDateEditor(df, false);
    > binder.registerCustomEditor(Date.class, editor);
    > }
    >
    >
    > The data binding process is behaving as I would expect. If the user
    > types an invalid date into the textbox, then the field cannot be bound
    > and the framework adds a FieldError to the Errors object with code
    > "typeMismatch". Unfortunately, this FieldError results in a very
    > un-user-friendly error message being put on the screen. The text of
    > the message is:
    >
    > "Failed to convert property value of type [java.lang.String] to
    > required type [java.util.Date] for property billDate; nested exception
    > is java.lang.IllegalArgumentException: Could not parse date:
    > Unparseable date: "xyz" "
    >
    >
    > It is not at all clear to me how to transform this ugly error message
    > to a user-friendly message. I can think of a number of possible ways
    > of doing this, but all seem overly-complex. Is there a standard way to
    > map data-binding errors to user-friendly messages? Thanks in advance
    > for your help.
    >
    >
    > Regards,
    > Craig
    , Jun 25, 2006
    #2
    1. Advertising

  3. javadude Guest

    Thanks for the info. Where (online/book) is this documented?


    wrote:
    > Have the customized typeMismatch message in your message properties
    > file that Spring load as messageResource.
    >
    > Example:
    > # For generic error message on type mismatch Date
    > typeMismatch.java.util.Date={0} is an invalid date.
    >
    > # For specific error message on perticular form field
    > # (e.g. startDt is a form field name)
    > typeMismatch.startDt=Start Date is an invalid date.
    >
    > Cheers,
    > Liu Jian
    >
    >
    > wrote:
    > > Dear Spring MVC experts!
    > >
    > > I am using a controller of type AbstractWizardFormController to
    > > implement a multi-page form entry workflow. This controller operates
    > > on a session-scoped command object which has a property of type
    > > java.util.Date. On page 3 of the wizard, the user enters a date into a
    > > textbox which will be bound to a java.util.Date property of the command
    > > object.
    > >
    > > In my controller, I am registering a custom editor as follows:
    > >
    > > protected void initBinder(HttpServletRequest request,
    > > ServletRequestDataBinder binder) throws Exception {
    > > DateFormat df = new SimpleDateFormat("MM/dd/yyyy");
    > > CustomDateEditor editor = new CustomDateEditor(df, false);
    > > binder.registerCustomEditor(Date.class, editor);
    > > }
    > >
    > >
    > > The data binding process is behaving as I would expect. If the user
    > > types an invalid date into the textbox, then the field cannot be bound
    > > and the framework adds a FieldError to the Errors object with code
    > > "typeMismatch". Unfortunately, this FieldError results in a very
    > > un-user-friendly error message being put on the screen. The text of
    > > the message is:
    > >
    > > "Failed to convert property value of type [java.lang.String] to
    > > required type [java.util.Date] for property billDate; nested exception
    > > is java.lang.IllegalArgumentException: Could not parse date:
    > > Unparseable date: "xyz" "
    > >
    > >
    > > It is not at all clear to me how to transform this ugly error message
    > > to a user-friendly message. I can think of a number of possible ways
    > > of doing this, but all seem overly-complex. Is there a standard way to
    > > map data-binding errors to user-friendly messages? Thanks in advance
    > > for your help.
    > >
    > >
    > > Regards,
    > > Craig
    javadude, Jun 27, 2006
    #3
  4. DaveHarris

    Joined:
    Oct 17, 2007
    Messages:
    1
    Handling Parameters in typeMismatch

    Hi Guys,

    I read your thread with interest, as "typeMismatch.java.util.Date={0} is an invalid date" is exactly what I want. The only problem I have however is that when {0} is expanded out, it replaces that with the bound field name, which is usually a non-user friendly name like 'startDate'.

    I want to be able to put my own string in there like I can do in my own form validator:
    error.rejectValue("numAxles", "validation.error.field.numberMismatch", new Object[] {"The number of axles"}, null); where validation.error.field.numberMismatch={0} must be a number

    Is there a way to control the parameter sent to {0} while in the spring binding process. While I can just use my own validator, it seems kindof silly to re-invent the wheel when its something that spring provides us, I just want to configure it.

    Cheers and thanks for any help in advance
    Dave
    DaveHarris, Oct 17, 2007
    #4
  5. andrei001

    Joined:
    Nov 30, 2007
    Messages:
    1
    I have a similar problem, and perhaps someone here knows the answer. I am using a date field in a search page, binding it using a customDateEditor, and using a validator for correct formatting. The problem i have is this: i am using the <spring:bind> tag so that the page will return with the value that caused a validation fault. But even if the page succeeds it is submitted back onto itself, this time carrying the search results. But this time the date field will return in a completly different format. I cannot use the <fmt:formatDate> tag because of <spring:bind>. How can i register a "reverse" bind editor if you will, something that will print my data according to a specific format depending on the class?

    Code snippet follows :
    <spring:bind path="filesRequest.fileEndDateSearch">
    <input type="text" id="fileEndDateSearch" name="fileEndDateSearch" class="txtBox" value="<fmt:formatDate value="${status.value}" type="date" pattern="yyyy-MM-dd" />"/>
    </spring:bind>

    Using <fmt:formatDate> for the ${status.value} will cause an exception in case the validator fails, as the format date tag will try to parse the erroneous input.
    andrei001, Nov 30, 2007
    #5
  6. jenueheightz

    Joined:
    Mar 7, 2008
    Messages:
    1
    If we put the key-value pair for all the labels for the fields into messages.properties, we can make it more user friendly.

    label.numAxles=The number of axles
    validation.error.field.numberMismatch={0} must be a number

    errors.rejectValue("numAxles", "validation.error.field.numberMismatch",
    new Object[]{ new DefaultMessageSourceResolvable(new String[]{"label.numAxles"})},"");


    Passing the key "label.numAxles" to the {0} would result to a message like "The number of axles must be a number". Not passing a fieldname to the {0} which is "numAxles" which results to "numAxles must be a number" which is not more user friendly.


    -jenue
    Last edited: Nov 14, 2009
    jenueheightz, Mar 7, 2008
    #6
  7. rishabh2u

    Joined:
    Nov 11, 2009
    Messages:
    1
    This is a nice and neat feature I feel. I used below to parse a check box in a form into a boolean field in Command.

    Code:
    	/**
    	 * This is an overridden verison of initBinder method of Spring baseCommandController.
    	 * It is used by Spring to register a custom editor for a String field coming in a 
    	 * Http request. This lets you have any datatype in your command and not just String.
    	 */
    	protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Exception {
    		binder.registerCustomEditor(Boolean.class, new CustomBooleanEditor(true));
    	}
    rishabh2u, Nov 11, 2009
    #7
  8. ahsan_cse2004

    Joined:
    Sep 21, 2010
    Messages:
    2
    Hi,
    I am sorry to resurrect this old thread, but did you find the solution to your problem. I have the same issue. I am setting the dates from my controller class and it is not visible on UI. I have already setup CustomDateEditor for Date class.

    Thanks
    Ahsan
    ahsan_cse2004, Sep 21, 2010
    #8
  9. ahsan_cse2004

    Joined:
    Sep 21, 2010
    Messages:
    2
    I did it as follows
    Code:
    <spring-tags:bind path="startDate">
           <input type="text" value="<fmt:formatDate value="${startDate}"  type="date" pattern="yyyy-MM-dd"/>" id="impressionReportStartDate" name="startDate"/>
    </spring-tags:bind>
    
    
    Where startDate is coming from my server code. Somehow I had to use name="startDate" also because path="startDate" alone did not work for me.

    Thanks
    Ahsan
    ahsan_cse2004, Sep 21, 2010
    #9
  10. Naga Syamala A

    Joined:
    Feb 17, 2012
    Messages:
    1
    Problem with CustomDateEditor


    Hi All,

    I am also getting same type of probelm.

    I am using date format is MM/dd/yyyy HH:mm

    In my controller CustomDateEditorcode is like given below

    @InitBinder protected void initBinder(final WebDataBinder dataBinder) {
    final SimpleDateFormat dateFormat = new SimpleDateFormat(
    "MM/dd/yyyy HH:mm");
    dataBinder.registerCustomEditor(Date.class,
    new CustomDateEditor(dateFormat, true));
    }

    and in my velocity file the code is lke this:

    <input type="text" id="start" name="start" value="$!date.format('MM/dd/yyyy H:m',$!campaign.start)" size="30" class='field text small #if($status.error) error #end' tabindex="4" />

    If user entered date as : 19/02/2012 11:53 , then it is not ging any error or exception simply accepting and taken as Tue Jul 02 11:53:00 IST 2013.

    Can anybody tell me the way how to strict the month value to maximum 12.

    Thanks,
    Syamala.
    Naga Syamala A, Feb 17, 2012
    #10
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Kenneth McDonald
    Replies:
    1
    Views:
    374
    Peter Hansen
    Jun 16, 2004
  2. rmn190
    Replies:
    2
    Views:
    2,352
    Arne Vajhøj
    Jan 10, 2008
  3. Goldfish
    Replies:
    1
    Views:
    696
    Goldfish
    Nov 6, 2008
  4. Praveen Bengeri
    Replies:
    1
    Views:
    304
    Tom Kaminski [MVP]
    Apr 19, 2004
  5. Sam
    Replies:
    1
    Views:
    160
    A. Sinan Unur
    Feb 20, 2007
Loading...

Share This Page