5

I'm hoping someone can help me since I have been banging my head against a wall for a couple of days on a issue which seems straightforward and which has been documented in other threads on the web.

I am using Smart GWT client (3.0) in conjunction with Spring 3.1 server and using JSON to communicate (with Jackson API 1.9).

The issue is that when I attempt to save a date from my SmartGWT client and it is sent 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 have seen this issue in a few other posts, but most relate to not having formatted the Date in the correct format, but I have tried various formats: - yyyy-MM-dd - yyyy-MM-dd'T'HH:mm:ssZ - yyyyMMddHHmmssZ (as per suggestion here: http://code.google.com/p/usersapi/issues/detail?id=8)

So in my code I have done the following:

  1. Configured a 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);
}

} `

  1. Spring app context thusly:

`

<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>

`

  1. 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:

  1. Controller Class

This may be where the issue lies, since 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 fetch data from the server and the date is displayed in SmartGWT fine. It's only when I do the add data that I get the issue. From 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 with this is hugely appreciated.

Cheers, Steve

3 Answers 3

13

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

Had to use Spring's 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)); }

Sign up to request clarification or add additional context in comments.

Comments

7

You should add DateFormat into 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)

Comments

0

I might be wrong, but as far as I remember the Z stands for timezone in ISOwhoknowswhatformat. And that's 4 chars wide, so I would try this:

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

By the way: if this is the issue you should've catched it in your unit tests. You do have unit test for CustomObjectMapper don't you? :P

2 Comments

Thanks for the reply, I tried updating to the format yo suggested, but I get the same exception: org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 errors Field error in object 'comment' on field 'dateAdded': rejected value [2012-06-27T12:39:40GMT+01:00]; So it's not valid either.
Create a unit test and try to manually parse data, then tell spring to do it. You would surely catch the error with some debugging.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.