2011-01-24 84 views
7

我使用球衣和杰克逊一起开发我的REST API,并且在反序列化日期字符串时遇到问题。我在泽西岛注册提供类:泽西+杰克逊反序列化失败与日期对象

@Provider 
public class MyJsonProvider extends JacksonJsonProvider { 
    public static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss"; 
    @Override 
    public void writeTo(Object value, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String,Object> httpHeaders, OutputStream entityStream) throws IOException, WebApplicationException { 
     ObjectMapper mapper = locateMapper(type, mediaType); 
     // Enable human readable date format 
     SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT); 
     mapper.getDeserializationConfig().setDateFormat(sdf); 
     mapper.getSerializationConfig().setDateFormat(sdf); 
     // Enable JAXB annotation, with Jackson annotation being the preferred one. 
     AnnotationIntrospector primary = new JacksonAnnotationIntrospector(); 
     AnnotationIntrospector secondary = new JaxbAnnotationIntrospector(); 
     AnnotationIntrospector introspector = new AnnotationIntrospector.Pair(primary, secondary); 
     mapper.getDeserializationConfig().setAnnotationIntrospector(introspector); 
     mapper.getSerializationConfig().setAnnotationIntrospector(introspector); 
     super.writeTo(value, type, genericType, annotations, mediaType, httpHeaders, entityStream); 
    } 
} 

而现在似乎泽西在启动过程中把它捡起来:

Jan 24, 2011 2:53:23 PM com.sun.jersey.api.core.ScanningResourceConfig logClasses 
INFO: Provider classes found: 
    class com.mypackage.MyJsonProvider 

它的序列化工作正常,但是当我试图反序列化的字符串像2010-01-25 00:00:00,我得到一个映射错误:

SEVERE: Servlet.service() for servlet JerseyWebApplication threw exception 
org.codehaus.jackson.map.JsonMappingException: Can not construct instance of java.util.Date from String value '2010-01-25 00:00:00': not a valid representation (error: Can not parse date "2010-01-25 00:00:00": not compatible with any of standard forms ("yyyy-MM-dd'T'HH:mm:ss.SSSZ", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", "EEE, dd MMM yyyy HH:mm:ss zzz", "yyyy-MM-dd")) 
at [Source: [email protected]; line: 3, column: 37] 
    at org.codehaus.jackson.map.JsonMappingException.from(JsonMappingException.java:159) 
    at org.codehaus.jackson.map.deser.StdDeserializationContext.weirdStringException(StdDeserializationContext.java:222) 
    at org.codehaus.jackson.map.deser.StdDeserializer._parseDate(StdDeserializer.java:283) 
    at org.codehaus.jackson.map.deser.DateDeserializer.deserialize(DateDeserializer.java:26) 
    at org.codehaus.jackson.map.deser.DateDeserializer.deserialize(DateDeserializer.java:17) 
    at org.codehaus.jackson.map.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:135) 
    at org.codehaus.jackson.map.deser.SettableBeanProperty$MethodProperty.deserializeAndSet(SettableBeanProperty.java:221) 
    at org.codehaus.jackson.map.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:391) 
    at org.codehaus.jackson.map.deser.BeanDeserializer.deserialize(BeanDeserializer.java:286) 
    at org.codehaus.jackson.map.ObjectMapper._readValue(ObjectMapper.java:1568) 
    at org.codehaus.jackson.map.ObjectMapper.readValue(ObjectMapper.java:788) 
    at org.codehaus.jackson.jaxrs.JacksonJsonProvider.readFrom(JacksonJsonProvider.java:398) 
    at com.sun.jersey.spi.container.ContainerRequest.getEntity(ContainerRequest.java:454) 

好像球衣依然采用JacksonJsonProvider以某种方式处理反序列化。我不知道我做错了什么。我应该如何在球衣内配置杰克逊?谢谢!

+7

我想通了自己创建自己的映射对象。原来,我需要在readFrom()方法中设置反序列化配置,而不是writeTo()方法。咄。 – fei 2011-01-25 01:04:51

回答

2

super.writeTo方法再次调用locateMapper(type,mediaType)并创建一个mapper对象的新实例,因此从不使用配置dateformat的mapper对象。 您可以在调试模式下确认。

你可以做的是通过创建一个构造

MyJsonProvider(){ 

    ObjectMapper mapper = new ObjectMapper(); 
    // Enable human readable date format 
    SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT); 
    mapper.getDeserializationConfig().setDateFormat(sdf); 
    mapper.getSerializationConfig().setDateFormat(sdf); 
    // Enable JAXB annotation, with Jackson annotation being the preferred one. 
    AnnotationIntrospector primary = new JacksonAnnotationIntrospector(); 
    AnnotationIntrospector secondary = new JaxbAnnotationIntrospector(); 
    AnnotationIntrospector introspector = new AnnotationIntrospector.Pair(primary, secondary); 
    mapper.getDeserializationConfig().setAnnotationIntrospector(introspector); 
    mapper.getSerializationConfig().setAnnotationIntrospector(introspector); 
    super(mapper);} 

然后你不需要重写的writeTo方法