Announcement Announcement Module
Collapse
No announcement yet.
Problems resolving error messages for arrays of objects Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Problems resolving error messages for arrays of objects

    I'm having problems getting error messages resolved for arrays of objects

    I have a view which displays multiple dates. These dates are bound to a date array on the command object associated with a SimpleFormController subclass.
    I've registered a custom property editor for the dates and using velocity's dateTool, I convert them to dd/mm/yyyy format in my template.

    The binding works correctly and the dates are displayed in dd/mm/yyyy format. However, if I put a set of characters into a date field that the date formatter cannot parse, a get a nasty null pointer exception on submit, rather than the typeMismatch error I was expecting.

    Here is the exception and a simplified version of the code:

    Exception:
    Code:
    org.apache.velocity.exception.MethodInvocationException: Invocation of method 'getMessage' in  class org.springframework.web.servlet.support.RequestContext threw exception class java.lang.NullPointerException : null
    	at org.apache.velocity.runtime.parser.node.ASTMethod.execute(Ljava.lang.Object;Lorg.apache.velocity.context.InternalContextAdapter;)Ljava.lang.Object;(ASTMethod.java:246)
    	at org.apache.velocity.runtime.parser.node.ASTReference.execute(Ljava.lang.Object;Lorg.apache.velocity.context.InternalContextAdapter;)Ljava.lang.Object;(ASTReference.java:175)
    ...
    Controller:
    Code:
    public class TestController  extends SimpleFormController{
    
    	protected SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
    
    	protected Object formBackingObject(HttpServletRequest request) throws ServletException {
    
    		TestCommandObject obj = new TestCommandObject();
    		obj.setMydates(new Date[]{
    				new Date(System.currentTimeMillis()),
    				new Date(System.currentTimeMillis()),
    				new Date(System.currentTimeMillis())
    								});
    		return obj;
    	}
    
    	protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) {
    		dateFormat.setLenient(true);
    		binder.registerCustomEditor(Date.class, null, new CustomDateEditor(dateFormat, true));
    	}
    }
    Command Object:
    Code:
    public class TestCommandObject {
    
    	private Date[] mydates;
    	
    	public Date[] getMydates() {
    		return mydates;
    	}
    
    	public void setMydates(Date[] mydates) {
    		this.mydates = mydates;
    	}
    }
    message properties file fragment:
    Code:
    typeMismatch.command.mydates[0]=Top Code matched
    typeMismatch.java.util.Date=Object Type matched
    typeMismatch=General type mismatch
    Velocity template fragment:
    Code:
    <tr>
    	#foreach &#40; $mydate in $command.mydates &#41;
    
    	<td>
    	<input type="text" name="mydates&#91;$velocityCount&#93;" value="$!dateTool.format&#40;"dd/MM/yyyy", $!mydate&#41;" />
    	</td>
    
    </tr>
    <tr>
    <td>
    #if&#40; $errors &#41;
    	#if&#40; $errors.getFieldErrors&#40; $field &#41; &#41;
    		#foreach&#40; $err in $errors.getFieldErrors&#40; $field &#41; &#41;
    			<span class="error">$rc.getMessage&#40;$err&#41;</span>
    		#end
    	#end
    #end
    </td>
    </tr>
    #end
    debugging the resulting BindException if I submit "NOTADATE" into the second date input field:
    Code:
    errors = &#123;org.springframework.validation.BindException@8625&#125;
    	errors&#58; java.util.List = &#123;java.util.LinkedList@8626&#125; size = 1
    		&#91;0&#93; = &#123;org.springframework.validation.FieldError@8636&#125;
    			field&#58; java.lang.String = "mydates&#91;1&#93;"
    			rejectedValue&#58; java.lang.Object = "NOTADATE"
    			bindingFailure&#58; boolean = true
    			objectName&#58; java.lang.String = "command"
    			codes&#58; java.lang.String&#91;&#93; = &#123;java.lang.String&#91;6&#93;@8639&#125;
    				&#91;0&#93; = "typeMismatch.command.mydates&#91;1&#93;"
    				&#91;1&#93; = "typeMismatch.command.mydates"
    				&#91;2&#93; = "typeMismatch.mydates&#91;1&#93;"
    				&#91;3&#93; = "typeMismatch.mydates"
    				&#91;4&#93; = "typeMismatch.java.util.Date"
    				&#91;5&#93; = "typeMismatch"
    			arguments&#58; java.lang.Object&#91;&#93; = &#123;java.lang.Object&#91;1&#93;@8640&#125;
    				&#91;0&#93; = &#123;org.springframework.context.support.DefaultMessageSourceResolvable@8648&#125;
    				codes&#58; java.lang.String&#91;&#93; = &#123;java.lang.String&#91;2&#93;@8649&#125;
    					&#91;0&#93; = "command.mydates&#91;1&#93;"
    					&#91;1&#93; = "mydates&#91;1&#93;"
    				arguments&#58; java.lang.Object&#91;&#93; = null
    				defaultMessage&#58; java.lang.String = "mydates&#91;1&#93;"
    			defaultMessage&#58; java.lang.String = "Failed to convert property value of type &#91;java.lang.String&#93; to required type &#91;java.util.Date&#93; for property 'mydates&#91;1&#93;'; nested exception is java.lang.IllegalArgumentException&#58; Could not parse date&#58; Unparseable date&#58; \"NOTADATE\""
    Note that because I've added the message property command.mydates[0], the first failure does print a helpful message ("Top code matched"), but the other fields cause the exception to be thrown, which indicates that the message code resolution order detailed in DefaultMessageCodesResolver JavaDocs (and replicated in the debugging above) doesn't seem to be working.

    What am I doing wrong? Is this linked to the registered property editor in any way? I would be very grateful for any help...

    Jon
Working...
X