当前位置: 首页 > 知识库问答 >
问题:

包括枚举类型以与jackson一起序列化和反序列化

孔嘉茂
2023-03-14

我有一个简单的枚举,我想序列化和反序列化。该类如下所示:

    public enum TipusViatge {
    OCI,
    NEGOCIS,
    FAMILIA;

    @Override
    public String toString() {
        return name().toUpperCase();
    }
}

问题是,我通过restful调用发送它,接收方可以接收任何类型(因此它只知道它将接收对象)。所以Jackson应该能够找出反序列化它的参数类型。

有可能这样做吗?我认为在生成的json中包含类名应该可以让Jackson判断出类型,但我一直无法做到这一点。

共有1个答案

乐正涵意
2023-03-14

我已经研究这个问题一段时间了。

首先,您可以使用Map反序列化json

第二,在一般情况下,你总是知道你读什么样的东西。这是顶级对象,您可以将其设置为Jackson mapper:mapper。阅读器(cls)。readValue(json)。如果枚举是这个cls对象的一部分,那么Jackson知道类型,只需读取值并对其进行解析。

第三,一个json字符串实际上可以有多个对象。我说的是继承。您可以查看Jackson留档中的@JsonTypeInfo

第四个假设你读了一个json源,但不知道你读了什么。在这种情况下,你可以要求Jackson在对象的开头写标记。就像你询问类名一样。我认为它与@JsonRootName有关。你可以在这里查看:Jackson JSON使用根元素反序列化

我认为现在在Jackson中如何处理对象是干净的。我的意思是我们知道如何告诉Jackson我们想要反序列化的元素。现在我们有一个问题:如何序列化json-

5这不是问题,是现成的。Jackson使用方法序列化枚举,并使用方法反序列化。您可以在Jackson中的EnumDeserializer中仔细查看它。

我不喜欢这种行为,因为它是个案。我面临的情况是,当人们手动编写json字符串时,使用小写,无法对其进行反序列化。此外,我认为,将枚举常量直接写入json文件是一种糟糕的做法,因为如果我想重构枚举的名称,那么也应该修改所有现有的json字符串(brrr)。为了解决这些问题,我做了以下技巧:1。使用默认的parseId(String id)实现EnumId接口,使用getId()识别枚举常数,并使用忽略大小写进行比较。1.我将id字段添加到枚举2中。为序列化3添加getId()。为反序列化4添加解析id(字符串id)。使用我的客户序列化程序(it)在Jackson ObjectMapper中添加新模块

should use `getId()` instead of `name()`).
if (enumId != null) {
    generator.writeString(enumId.getId());
}

我想这都是关于这个话题的。我给你一个代码示例,让它更清楚(最好写一次,然后解释两次):

public interface EnumId {

    String name();

    default String getId() {
        return name().toLowerCase();
    }

    static <T extends Enum<?> & EnumId> T parseId(Class<T> cls, String id) {
        T res = parseId(cls.getEnumConstants(), id, null);

        if (res != null) {
            return res;
        }

        throw new EnumConstantNotPresentException(cls, id);
    }

    static <T extends EnumId> T parseId(T[] values, String id, T def) {
        for (T value : values) {
            if (id != null ? id.equalsIgnoreCase(value.getId()) : value.getId() == null) {
                return value;
            }
        }

        return def;
    }

    static <T extends EnumId> T get(T value, T def) {
        return value != null ? value : def;
    }
}

public enum TipusViatge implements EnumId {
    OCI,
    NEGOCIS,
    FAMILIA;

    @JsonCreator
    public static TipusViatge parseId(String id) {
        return EnumId.parseId(TipusViatge.class, id);
    }
}
 类似资料:
  • 问题内容: 我正在使用JAVA 1.6和Jackson 1.9.9我有一个枚举 我添加了一个@JsonValue,这似乎可以将对象序列化为: 但是当我尝试反序列化时,我得到了 我在这里想念什么? 问题答案: 如果你希望将枚举类与其JSON表示完全脱钩,则@xbakesx指出的序列化器/反序列化器解决方案是一个很好的解决方案。 另外,如果你喜欢一个独立的解决方案,则基于·和·注释的实现会更方便。 因

  • 我使用的是JAVA 1.6和Jackson 1.9.9我有一个枚举 我添加了一个@jsonValue,这似乎完成了它将对象序列化为:

  • 问题内容: 我正在尝试并且未能对Jackson 2.5.4的枚举进行反序列化,并且我不太清楚我的情况。我的输入字符串是驼峰式的,我想简单地映射到标准的Enum约定。 我也尝试了吸气剂,但没有成功,这是我在其他地方看到的一种选择。他们都炸毁了: 我究竟做错了什么? 问题答案: 编辑: 从Jackson 2.6开始,您可以在枚举的每个元素上使用以指定其序列化/反序列化值(请参见此处): (此答案的其余

  • 我正在尝试使用jackson-DataBind Objectmapper反序列化一个JSON字符串,其中包含一组枚举属性。当JSON中出现未在枚举中定义的未知属性时,就会发生这种情况。请在下面找到我正在使用的对象映射器配置。 但是,反序列化(ObjectMapper.ReadValue(jsonText,.class);)抛出此错误。“test”是要反序列化的JSON字符串中的未知属性。 Com.

  • 问题内容: 考虑以下枚举和类: 并考虑以下主要功能: 当前,该主输出为: 这种输出并不适合我,因为除了字符串的,我想它是,这是序号值在枚举。 所以我想要得到的实际结果是: 有一些优雅的方法可以使其表现为这种方式吗? 问题答案: 它应该通过指定映射器来工作。 如注解的Javadoc所述,这也适用于反序列化: 注意:当用于Java枚举时,一个附加功能是带注释的方法返回的值也被视为要反序列化的值,而不仅

  • 我有JSON反序列化和映射到枚举的问题。我从外部API获取JSON,类似于下面两个例子: 我想将空值映射到一些默认的枚举值。 模型对象 和枚举类 对于exists,值模型类包含正确的枚举,但如果我从API获取< code>null,它在模型中仍然是< code>null。 我试图创建一些由< code>@JsonCreator注释的方法,使用< code > @ JsonEnumDefaultVa