json Spring 3.0 异常在 POST 上将 String 转换为 java.util.Date
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11224028/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Spring 3.0 exception converting String to java.util.Date on POST
提问by Stephen Harper
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 Hymanson API 1.9).
我将 Smart GWT 客户端 (3.0) 与 Spring 3.1 服务器结合使用,并使用 JSON 进行通信(使用 Hymanson 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:
问题是,当我尝试从 SmartGWT 客户端保存日期并将其发送到服务器时,出现以下异常:
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)
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)
我在其他一些帖子中看到过这个问题,但大多数与没有以正确格式格式化日期有关,但我尝试了各种格式: - yyyy-MM-dd - yyyy-MM-dd'T'HH:mm :ssZ - yyyyMMddHHmmssZ(根据这里的建议:http: //code.google.com/p/usersapi/issues/detail?id=8)
So in my code I have done the following:
所以在我的代码中我做了以下事情:
- Configured a CustomObjectMapper:
- 配置了一个 CustomObjectMapper:
` public class CustomObjectMapper extends ObjectMapper {
` 公共类 CustomObjectMapper 扩展了 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 app context thusly:
- 因此,Spring 应用程序上下文:
`
`
<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.MappingHymansonHttpMessageConverter">
<property name="objectMapper" ref="HymansonObjectMapper" />
<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.MappingHymansonHttpMessageConverter">
<property name="supportedMediaTypes" value="application/json" />
<property name="objectMapper" ref="HymansonObjectMapper" />
</bean>
<bean id="HymansonObjectMapper" 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;
` 导入 java.util.Date;
@JsonAutoDetect public class Comment {
@JsonAutoDetect 公共类评论{
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 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.
这可能是问题所在,因为当我使用 @RequestBody 时,它可以通过我的集成测试工作,但是,SmartGWT 中的抽象 RestDataSource 仅适用于 @ModelAttribute,所以我不确定如何继续。
@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);
}
@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:
所以我可以从服务器获取数据并且日期显示在 SmartGWT 中。只有当我添加数据时才会出现问题。从智能 GWT 开发者控制台:
{
"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"
}
{
"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
干杯,史蒂夫
回答by Stephen Harper
I found out the issue thanks to http://vkubushyn.wordpress.com/2011/05/31/smart-gwt-restful-spring-mvc
感谢http://vkubushyn.wordpress.com/2011/05/31/smart-gwt-restful-spring-mvc,我发现了这个问题
Had to use Spring's InitBinder
不得不使用 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));
}
@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));
}
回答by egemen
You should add DateFormat into your model.
您应该将 DateFormat 添加到您的模型中。
@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)
回答by Gergely Szilagyi
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:
我可能是错的,但据我所知,Z 代表 ISOwhoknowswhatformat 中的时区。这是 4 个字符宽,所以我会试试这个:
new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZZZZ");
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 CustomObjectMapperdon't you? :P
顺便说一句:如果这是问题,您应该在单元测试中发现它。你确实有单元测试,CustomObjectMapper不是吗?:P

