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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13432761/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 12:41:02  来源:igfitidea点击:

Serialize class with generic to JSON using Hymanson

javajsongenericsdateserialization

提问by James2707

I have a structure of objects representing a Questionnaire and I need to serialize to JSON. One class of the structure is a OpenQuestion and this class use generics with two parameters. The problem starts when one of types used was Date, the date is serialized wrong, like a long.

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

Class code:

班级代码:

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

I saw how to serialize a date in a hash map if the hash map always uses a Date, but in this case I use the class with String, Integer or Date.

如果散列映射总是使用日期,我看到了如何在散列映射中序列化日期,但在这种情况下,我使用带有字符串、整数或日期的类。

Any idea to solve it? Thanks

任何想法来解决它?谢谢

采纳答案by Perception

As pointed out by @MiserableVariable, Hymanson serializes (most) date fields as (numeric long) timestamps by default. You can override this behavior in a number of ways.

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

If using your own instance of ObjectMapper, override a property to write dates as ISO-8601:

如果使用您自己的 ObjectMapper 实例,请覆盖一个属性以将日期写入 ISO-8601:

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

If using your own instance of ObjectMapper, to have dates written in your own custom format:

如果使用您自己的 ObjectMapper 实例,以您自己的自定义格式写入日期:

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

To leave the default serialization behavior for most fields, but override it for certain fields on certain objects, use a custom serializer:

要保留大多数字段的默认序列化行为,但为某些对象上的某些字段覆盖它,请使用自定义序列化程序:

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

All of this information is available in the Hymanson Documentation, with the bulk of it in the sectiondealing with date handling.

所有这些信息都可以在Hymanson 文档 中找到,其中大部分在处理日期处理的部分

回答by Calum

You can add a JsonTypeInfoannotation for this. There's two ways of using this:

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

  • Get it to automatically add a type annotation to your object, so it knows what to deserialize it as.
  • Add a custom type resolver, to handle this for you.
  • 让它自动向您的对象添加类型注释,因此它知道将其反序列化为什么。
  • 添加自定义类型解析器,为您处理此问题。

The first will make your JSON ugly, but requires very little extra code and doesn't force you to make custom serializers. The latter is more difficult, but will result in cleaner JSON. Overall the problem is partly that one of your types isn't modelled in JSON (Date) so you'll probably need it to be serialised as an integer or String type in your JSON file.

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

The former option looks a bit like this:

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

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

This shouldencode say, a String value, as something like:

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

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

No promises on that being accurate as this is mostly from memory!

不保证准确,因为这主要来自记忆!

回答by StaxMan

It depends. If you do know expected type, you just pass generic type reference:

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

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

as that clues Hymanson in as to expected type.

因为这暗示了Hyman逊的预期类型。

If you do not know it, then the other answer shows how to use @JsonTypeInfo.

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