2012-11-17 23 views
2

我有一个代表问卷的对象结构,我需要序列化为JSON。 结构的一个类是OpenQuestion,此类使用具有两个参数的泛型。 当使用的类型之一是Date时,该问题开始,日期序列化错误,如long。使用杰克逊泛型到JSON的Serialize类

类代码:

public class OpenQuestion <valueType,validationType> extends AbstractQuestion implements Serializable { 
    private valueType value; 
    private validationType minValue; 
    private validationType maxValue; 
    ... 
} 

我看到如何序列日期在哈希表,如果散列图总是使用日期,但在这种情况下,我用字符串,整数或日期的类。

任何想法解决它? 谢谢

+1

您是否做过任何搜索?我很快发现我没有使用杰克逊,但一个快速搜索导致我http://wiki.fasterxml.com/JacksonFAQDateHandling:'objectMapper.configure(SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS,false);' –

+2

是的,但我认为问题在于使用泛型的反序列化器,因为Jackson不知道这是一个日期还是什么 – James2707

回答

1

正如@MiserableVariable所指出的,杰克逊默认情况下将(大部分)日期字段序列化为(数字长)时间戳。您可以通过多种方式覆盖此行为。

如果使用自己的ObjectMapper的情况下,重写一个属性写日期为ISO-8601:

objectMapper.configure(SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS, false); 

如果使用自己的ObjectMapper的情况下,有写在自己的自定义格式的日期:

objectMapper.setDateFormat(myDateFormat); // 1.8 and above 
objectMapper.getSerializationConfig().setDateFormat(myDateFormat); // for earlier versions (deprecated for 1.8+) 

离开对于大多数字段的默认序列化行为,但覆盖它在某些对象的某些字段,可使用自定义序列:

public class MyBean implements Serializable { 
    private Date postDate; 

    // ... constructors, etc 

    @JsonSerialize(using = MyCustomDateSerializer.class) 
    public Date getPostDate() { 
     return postDate; 
    } 
} 

public class MyCustomDateSerializer extends JsonSerializer<Date> { 

    @Override 
    public void serialize(final Date date, final JsonGeneraror generator, 
      final SerializerProvider provider) throws IOException, 
      JSONProcessingException { 

     generator.writeString(yourRepresentationHere); 
    } 
} 

所有这些信息都可以在Jackson Documentation中找到,其中大部分信息在section中处理日期处理。

+0

好吧,这解决了串行化数据的问题。但是当我需要反序列化它时,这有效吗?请记住我使用泛型,杰克逊如何知道这需要在Date中反序列化而不是字符串?感谢您的帮助 – James2707

2

您可以为此添加JsonTypeInfo注释。有两种使用方式:

  • 获取它自动添加一个类型注释到你的对象,所以它知道什么将其反序列化为。
  • 添加自定义类型解析器,为您处理此问题。

第一个会让你的JSON变丑,但只需要很少的额外代码,并不会强制你制作自定义序列化器。后者更困难,但会导致更干净的JSON。总的来说,问题的部分原因是你的一个类型不是用JSON(Date)建模的,所以你可能需要将它在JSON文件中作为整数或字符串类型进行序列化。

前一种选择看起来有点像这样:

@JsonTypeInfo(use = Id.CLASS, include = As.WRAPPER_PROPERTY) 
private valiationType minValue; 

应该编码说,一个字符串值,就像这样:对被准确的,因为这

{ __type = "java.lang.String", value = "Hello, World" } 

没有承诺主要来自内存!

+0

错误,使用JsonTypeInfo不能解决OP的问题。 – Perception

+1

谢谢!这解决了问题! – James2707

+0

@Perception:我认为OP的两个参数是反序列化时间未知类型的主要问题,但是我从你的回答可以看出,如果没有定制,日期格式化也是“有点垃圾”的问题。这两个答案是必需的,以获得一个“漂亮”(有很好的日期)和明确的可解析的响应:) – Calum

2

这取决于。如果你知道预期的类型,你只是通过泛型类型参考:

OpenQuestion<Value,Validation> v = objectMapper.readValue(json, 
    new TypeReference<OpenQuestion<Value,Validation>>() { }); 

为线索杰克逊在为预期的类型。

如果您不知道,那么其他答案显示如何使用@JsonTypeInfo

+0

这真是一个好点!我完全忘记了这个功能,但在某些情况下它确实有意义。 – Calum