Spring 3.0 exception, converting String to java.util.Date to POST

I hope someone can help me as I banged my head on the wall for several days on a problem that seems simple and which has been documented in other streams on the Internet.

I use the Smart GWT client (3.0) in conjunction with the Spring 3.1 server and using JSON for communication (with Jackson API 1.9).

The problem is that when I try to save the date from my SmartGWT client and go to the server, I get the following exception:

org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 errors Field error in object 'comment' on field 'dateAdded': rejected value [2012-06-27T10:57:47+0100]; codes [typeMismatch.comment.dateAdded,typeMismatch.dateAdded,typeMismatch.java.util.Date,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [comment.dateAdded,dateAdded]; arguments []; default message [dateAdded]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.util.Date' for property 'dateAdded'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type java.lang.String to type java.util.Date for value '2012-06-27T10:57:47+0100'; nested exception is java.lang.IllegalArgumentException] at org.springframework.web.method.annotation.ModelAttributeMethodProcessor.resolveArgument(ModelAttributeMethodProcessor.java:110)

I saw this problem in several other posts, but most of them are related to the fact that it did not format the date in the correct format, but I tried various formats: - yyyy-MM-dd - yyyy-MM-dd'T'HH: mm : ssZ - yyyyMMddHHmmssZ (as suggested here: http://code.google.com/p/usersapi/issues/detail?id=8 )

So, in my code, I did the following:

  • Configuring CustomObjectMapper:

`public class CustomObjectMapper extends ObjectMapper {

 SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); public CustomObjectMapper() { super(); configure(Feature.WRITE_DATES_AS_TIMESTAMPS, false); setDateFormat(formatter); getDeserializationConfig().setDateFormat(formatter); } 

} `

  • Spring application context:

`

 <mvc:annotation-driven> <mvc:message-converters> <bean class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter"> <constructor-arg ref="jaxbMarshaller" /> <property name="supportedMediaTypes" value="application/xml"/> </bean> <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"> <property name="objectMapper" ref="jacksonObjectMapper" /> <property name="supportedMediaTypes" value="application/json" /> </bean> </mvc:message-converters> </mvc:annotation-driven> <context:component-scan base-package="com.jpmorgan.creditriskreporting.server" /> <bean id="marshallingConverter" class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter"> <constructor-arg ref="jaxbMarshaller" /> <property name="supportedMediaTypes" value="application/xml"/> </bean> <bean id="jsonConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"> <property name="supportedMediaTypes" value="application/json" /> <property name="objectMapper" ref="jacksonObjectMapper" /> </bean> <bean id="jacksonObjectMapper" class="com.jpmorgan.creditriskreporting.server.util.CustomObjectMapper" /> <!-- Client --> <bean id="restTemplate" class="org.springframework.web.client.RestTemplate"> <property name="messageConverters"> <list> <ref bean="marshallingConverter" /> <ref bean="jsonConverter" /> </list> </property> </bean> 

`

  • Bean object:

`import java.util.Date;

@JsonAutoDetect public class Comment {

 private int id; private String comment; private Date dateAdded; public Comment() {} public Comment(int id) { this.id = id; } 

...

 //@JsonSerialize(using=JsonDateSerializer.class) -- I had previously tried to use these custom Date serializer class public Date getDateAdded() { return dateAdded; } //@JsonDeserialize(using=JsonDateDeserializer.class) public void setDateAdded(Date dateAdded) { this.dateAdded = dateAdded; } 

`

EDIT:

  • Controller class

This may be a problem because when I use @RequestBody it works from my integration tests, however my abstract RestDataSource in SmartGWT only works with @ModelAttribute, so I'm not sure how to proceed.

@RequestMapping(value="/", method=RequestMethod.POST) public @ResponseBody Comment createNewComment2(@ModelAttribute Comment comment) { log.info("calling createComment with comment: {}", comment); comment.setDateAdded(new Date()); Comment added = commentDao.create(comment); log.info("created comment: {}", added); return commentDao.get(comment);
}

So, I can get the data from the server, and the date is displayed in SmartGWT in order. This is only when I do the addition of data that occurs to me. Using the Smart GWT Developer Console:

{ "dataSource":"CommentDS", "operationType":"add", "componentId":"isc_DynamicForm_1", "data":{ "userAdded":"sharper", "dateAdded":"2012-06-27T10:57:47+0100", "comment":"sample" }, "callback":{ "target":[DynamicForm ID:isc_DynamicForm_1], "methodName":"saveEditorReply" }, "showPrompt":true, "prompt":"Saving form...", "oldValues":{ }, "clientContext":{ }, "requestId":"CommentDS$6272" }

Any help on this is greatly appreciated.

Cheers, Steve

+4
source share
3 answers

I figured out the problem thanks to http://vkubushyn.wordpress.com/2011/05/31/smart-gwt-restful-spring-mvc

Had to use Spring InitBinder

@InitBinder public void initBinder(WebDataBinder binder) { SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); dateFormat.setLenient(false); binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false)); }

+9
source

You must add DateFormat to your model.

 @DateTimeFormat(pattern = "dd.MM.yyyy") private Date beginDate; @DateTimeFormat(pattern = "dd.MM.yyyy") private Date endDate; 

as a function parameter

  void functionName** (@RequestParam("beginDate") @DateTimeFormat(pattern = "dd.MM.yyyy")Date beginDate, @RequestParam("endDate") @DateTimeFormat(pattern = "dd.MM.yyyy")Date endDate) 
+3
source

Maybe I'm wrong, but as far as I remember, Z stands for the time zone in ISOwhoknowswhatform. And these are four characters, so I would try this:

new SimpleDateFormat ("yyyy-MM-dd'T'HH: mm: ssZZZZ");

By the way: if this is a problem, you should have caught it in your unit tests. You have a unit test for CustomObjectMapper , right ?: P

0
source

All Articles