使用Jackson将带有泛型的类序列化为JSON

时间:2012-11-17 17:09:24

标签: java json generics date serialization

我有一个代表调查问卷的对象结构,我需要序列化为JSON。 结构的一类是OpenQuestion,这个类使用带有两个参数的泛型。 当使用的类型之一是Date时,问题开始,日期序列化错误,如长。

班级代码:

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

如果哈希映射总是使用Date,我看到如何在哈希映射中序列化日期,但在这种情况下,我使用带有String,Integer或Date的类。

有什么想法解决它吗? 感谢

3 个答案:

答案 0 :(得分:3)

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

  • 让它自动为您的对象添加类型注释,因此它知道将其反序列化为什么。
  • 添加自定义类型解析程序,以便为您处理此问题。

第一个会让你的JSON变得丑陋,但只需要很少的额外代码,并且不会强迫你制作自定义序列化程序。后者更难,但会产生更清晰的JSON。总体而言,问题部分在于您的某个类型未在JSON(日期)中建模,因此您可能需要将其序列化为JSON文件中的整数或字符串类型。

前一个选项看起来有点像这样:

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

这个应该编码说一个字符串值,如:

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

没有任何承诺是准确的,因为这主要来自记忆!

答案 1 :(得分:3)

这取决于。如果您确实知道期望的类型,则只需传递泛型类型引用:

OpenQuestion<Value,Validation> v = objectMapper.readValue(json,
  new TypeReference<OpenQuestion<Value,Validation>>() { });
正如杰克逊所预期的类型一样。

如果您不知道,那么另一个答案会显示如何使用@JsonTypeInfo

答案 2 :(得分:1)

正如@MiserableVariable指出的那样,Jackson默认将(大多数)日期字段序列化为(数字长)时间戳。您可以通过多种方式覆盖此行为。

如果使用自己的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处理日期处理。