我同时使用 jersey 和 jackson 来开发我的 REST API,但在反序列化日期字符串时遇到问题。我已经在 Jersey 注册了一个提供者类:
@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);
}
}
而且 Jersey 似乎在启动过程中拾取了它:
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: org.apache.catalina.connector.CoyoteInputStream@6a3d899a; 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)
Jersey 似乎仍在使用 JacksonJsonProvider
以某种方式处理反序列化。我不确定我做错了什么。我应该如何配置 Jersey 内的 jackson ?谢谢!
最佳答案
super.writeTo 方法再次调用 locateMapper(type, mediaType) 并创建一个映射器对象的新实例,因此永远不会使用您配置日期格式的映射器对象。 您可以在 Debug模式下确认。
您可以做的是通过创建构造函数来创建自己的映射器对象
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方法
关于java - 带有日期对象的 Jersey + Jackson 反序列化失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4788175/