2011-01-24 33 views
7

Sto utilizzando jersey e jackson insieme per sviluppare la mia API REST e sto riscontrando un problema durante la deserializzazione di una stringa di data. Ho registrare una classe fornitore a Jersey:Errore di deserializzazione di Jersey + Jackson con oggetto data

@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); 
    } 
} 

e sembra Jersey raccolse durante l'avvio:

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

e funziona benissimo per la serializzazione, ma quando ho provato a deserializzare una stringa come 2010-01-25 00:00:00, sto ottenendo un errore di mapping:

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) 

sembra Jersey sta ancora utilizzando JacksonJsonProvider per gestire la deserializzazione in qualche modo. Non sono sicuro di cosa sto sbagliando. Come devo configurare il jackson all'interno della maglia? Grazie!

+7

ho capito io. È stato necessario impostare la configurazione di deserializzazione nel metodo readFrom(), non nel metodo writeTo(). Duh. – fei

+3

Perché è chiuso come "troppo localizzato"? Jersey con Jackson è uno scenario comune. – Paul

+5

@fei puoi aggiungerlo come risposta – eis

risposta

2

super.writeTo chiama di nuovo locateMapper (tipo, mediaType) e crea una nuova istanza di oggetto mapper in modo che l'oggetto del mapping su cui si configura il dataformat non venga mai utilizzato. È possibile confermare in modalità di debug.

Che cosa si può fare è creare il proprio oggetto mapper con la creazione di un costruttore

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);} 

Allora non avete bisogno di eseguire l'override del metodo WriteTo

Problemi correlati