2011-01-24 37 views
7

Tôi đang sử dụng áo và jackson với nhau để phát triển REST API của tôi, và tôi đang gặp một vấn đề khi deserializing một chuỗi ngày. Tôi có đăng ký một lớp nhà cung cấp ở Jersey:Jersey + Jackson deserialization thất bại với ngày đối tượng

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

Và nó có vẻ như Jersey nhặt nó lên trong khởi động:

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

Và nó hoạt động tốt cho serialization, nhưng khi tôi đã cố gắng để deserialize một chuỗi như 2010-01-25 00:00:00, tôi nhận được một lỗi lập bản đồ:

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) 

Nó có vẻ như Jersey vẫn sử dụng JacksonJsonProvider để xử lý các deserialization bằng cách nào đó. Tôi không chắc mình đang làm gì sai. Làm thế nào tôi nên cấu hình jackson trong áo? Cảm ơn!

+7

I figured it out bản thân mình. Hóa ra tôi cần thiết lập cấu hình deserialization trong phương thức readFrom(), không phải phương thức writeTo(). Duh. – fei

+3

Tại sao điều này bị đóng là "quá địa phương hóa"? Jersey với Jackson là một kịch bản phổ biến. – Paul

+5

@ fei bạn có thể thêm nó như là một câu trả lời – eis

Trả lời

2

super.writeĐối với các cuộc gọi phương thức định vịMapper (type, mediaType) một lần nữa và tạo một cá thể mới của đối tượng bản đồ để đối tượng bản đồ mà bạn định cấu hình dateformat không bao giờ được sử dụng. Bạn có thể xác nhận trong chế độ gỡ lỗi.

Những gì bạn có thể làm là tạo đối tượng mapper của riêng bạn bằng cách tạo ra một constructor

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

Sau đó, bạn không cần phải ghi đè lên các phương pháp writeTo

Các vấn đề liên quan