Page 1 of 2 12 LastLast
Results 1 to 10 of 19

Thread: Binding errors vs Validation errors

  1. #1
    Join Date
    Aug 2007
    Location
    Belgium
    Posts
    58

    Default Binding errors vs Validation errors

    Hi,

    I'm having a small difficulty maintaining my error messages. Let's say I have the following scenario:

    On my form, I have a field where I can enter a Date in a specific format. When entering no date or a non date value, an exception is thrown by Spring which will then be mapped by an error in my error.properties file (so that I don't see the verbose error message from spring in my page)
    On the other hand, I have validator specified to check if the date field is not empty.

    In my JSP, I loop over my errors and display each of them on top of the screen. When the date field was left empty, I will then see 2 messages for that date field. I could for example drop the validation of the date field in my validator. But the thing is, when I am having 2 date fields to enter, I want to specifiy in my error message which one was not valid. The binding error will display 2 times that there was an error on binding a Date.

    If someone could help me out, I would really appreciate that

  2. #2

    Default

    can you post some code snippet?

  3. #3
    Join Date
    Aug 2007
    Location
    Belgium
    Posts
    58

    Default

    Here is some code:

    Code:
    Init binder for the date values in the form
    
    @Override
    	protected void initBinder(HttpServletRequest request,
    			ServletRequestDataBinder binder) throws Exception {
    		//Create a custom binder that will convert a String with pattern dd/MM/yyyy to an appropriate Date object.
    		SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
    		binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false));
    	}
    Code:
    Code for validating dates:
    
    private void validatePage1(Object target, Errors errors) {
    		CampaignWizardData data = (CampaignWizardData) target;
    		//If the wizard is in update mode, don't do the validation there because the controller will redirect you to that page in case
    		//of errors, this is due to the fact that a check is done on the existence of a campaign with the filled in name.
    		if (!data.isUpdate() && !data.isCopy()) {
    		    ValidationUtils.rejectIfEmptyOrWhitespace(errors, "startDate", "errors.startDate","Please fill in a valid start date");
    		    ValidationUtils.rejectIfEmptyOrWhitespace(errors, "endDate", "errors.endDate","Please fill in a valid end date");
    		    if (data.getEndDate() != null && data.getStartDate() != null && data.getEndDate().before(data.getStartDate())) {
    	            errors.reject("errors.endDateBeforeStartDate", "The end date should come after the start date");
    	        }else if (data.getEndDate() != null && data.getStartDate() != null && data.getStartDate().before(DateUtils.addDays(DateUtils.truncate(new Date(), Calendar.DATE), 1))) {
    	            errors.reject("errors.startDateBeforeToday", "The start date should be at least one day after today");
    	        }
    	        if (pmgmFacade.checkExistingCampaignName(data.getName())) {
    	            errors.reject("errors.campaignName", "A campaign with this name already exists");
    	        }
    		}
    		
    }
    Code:
    Displayal of errors in the jsp page:
    
    ...
    <spring:bind path="campaignData.*">
    	<c:if test="${not empty status.errorMessages}">
    		<c:forEach items="${status.errorMessages}" var="error">
    			<c:out value="${error}" escapeXml="false"/> <br />
    	    </c:forEach>
    	</c:if>
    </spring:bind>
    
    ....

  4. #4
    Join Date
    Apr 2008
    Location
    Singapore
    Posts
    83

    Default

    your can have the following in your error.properties file..

    typeMismatch.startDate = Invalid Start Date
    typeMismatch.endDate = Invalid End Date

    cusstermize the messages for each property as you want...
    then drop the validation for empty string in your validator class for both properties.

    so when the user leave a date field empty or keys in a invalid input the relevent error message will be displayed..

  5. #5
    Join Date
    Aug 2007
    Location
    Belgium
    Posts
    58

    Default

    Thank you rukshan, that really did the trick

    I thought you could only map the errors on their type like 'typeMismatch.java.util.date'

  6. #6
    Join Date
    Jul 2008
    Location
    Almere
    Posts
    16

    Default

    actually there are some more available variables to map:

    inspecting the error object:

    Field error in object 'order' on field 'dateStart': rejected value [];
    codes [typeMismatch.order.dateStart,typeMismatch.dateStar t,typeMismatch.java.util.Date,typeMismatch];
    arguments [org.springframework.context.support.DefaultMessage SourceResolvable: codes [order.dateStart,dateStart];
    arguments [];
    default message [dateStart]];
    default message [Failed to convert property value of type [java.lang.String] to required type [java.util.Date] for property 'dateStart';
    nested exception is java.lang.IllegalArgumentException: Could not parse date: Unparseable date: ""]

    the codes section is what you're looking for, overriding any of the following codes in ur properties file will lead to custom messages:

    typeMismatch
    typeMismatch.java.util.Date
    typeMismatch.dateStart
    typeMismatch.order.dateStart

    where "order" is actually the name of the command you used on your form <spring:form commandName="order" ...>
    <spring:input path="dateStart">
    .. etc.

    dont forget to inject the commandname to your controller as well (or set it through the controllers constructor).

  7. #7
    Join Date
    Apr 2008
    Location
    Singapore
    Posts
    83

    Default

    you are welcome...

    If I'm not wrong the following mapping should work as well

    typeMismatch.campaignData.startDate = Invalid Start Date
    typeMismatch.campaignData.endDate = Invalid End Date

    generally its like typeMismatch.commandName.propertyName

  8. #8
    Join Date
    Aug 2007
    Location
    Belgium
    Posts
    58

    Default

    That's even a better solution. In that way, I could create different error messages even if the field names are the same for the command objects

  9. #9
    Join Date
    Jul 2008
    Location
    Almere
    Posts
    16

    Default

    It's even gonna be better. Check the error object again.

    there's a line saying this:
    arguments [org.springframework.context.support.DefaultMessage SourceResolvable: codes [order.dateStart,dateStart];

    if you gonna override one of those codes in you're properties file you can do something like this:

    order.dateStart=Order startdate
    typeMismatch.java.util.Date={0} is an invalid date

    the message will be resolved as:
    "Order startdate is an invalid date"

    Mixing a very generic date parsing error with a specific fieldname. One thing to consider is that you'd have to override the resolvable fieldname for each date field you use or the system will use the default name.

  10. #10
    Join Date
    Aug 2007
    Location
    Belgium
    Posts
    58

    Default

    Very nice. You did a great job finding this out I think it would be great if such examples would be in the reference manual (if it isn't already included of course)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •