java - 使用 Jackson 序列化类时添加类型信息,以便可以使用接口(interface)类型反序列化而不使用注释?

标签 java json jackson jackson-databind

这个问题类似于include class name in all objects serialized by jackson但我想默认配置此而不在每个类上使用注释。最好我想向序列化的 json 添加一个 field ,例如包含序列化类的类名的 _class_type (最好不是完全合格的 Activity ,但我对此表示同意)。我正在使用 Jackson 2.11.1。

例如,假设我有这个界面:

public interface MyInterface {}

和两个实现:

public class MyClass1 implements MyInterface {

    private String something;

    public String getSomething() {
        return something;
    }

    public void setSomething(String something) {
        this.something = something;
    }
}

public class MyClass2 implements MyInterface {
    
    private String somethingElse;

    public String getSomethingElse() {
        return somethingElse;
    }

    public void setSomethingElse(String somethingElse) {
        this.somethingElse = somethingElse;
    }
}

我希望能够序列化 MyClass1MyClass2 的实例,以便我可以将它们反序列化为 MyInterface (即添加类型序列化时的信息)。

我已阅读documentation您应该能够像这样配置ObjectMapper以使其工作:

PolymorphicTypeValidator ptv = BasicPolymorphicTypeValidator.builder().build();
objectMapper.activateDefaultTyping(ptv); // default to using DefaultTyping.OBJECT_AND_NON_CONCRETE

但是当我尝试这个时:

ObjectMapper objectMapper = new ObjectMapper();
PolymorphicTypeValidator ptv = BasicPolymorphicTypeValidator.builder().build();
objectMapper.activateDefaultTyping(ptv); // default to using DefaultTyping.OBJECT_AND_NON_CONCRETE

MyClass1 myClass1 = new MyClass1();
myClass1.setSomething("something");

String json = objectMapper.writeValueAsString(myClass1);

MyInterface myInterface = objectMapper.readValue(json, MyInterface.class);

我得到这个异常:

com.fasterxml.jackson.databind.exc.MismatchedInputException: Unexpected token (START_OBJECT), expected START_ARRAY: need JSON Array to contain As.WRAPPER_ARRAY type information for class org.something.MyInterface
 at [Source: (String)"{"something":"something"}"; line: 1, column: 1]

如果我更改配置以使用ObjectMapper.DefaultTyping.EVERYTHING,那么 Jackson 实际上似乎将类型包装在数组中,但在尝试反序列化时仍然遇到异常:

ObjectMapper objectMapper = new ObjectMapper();
PolymorphicTypeValidator ptv = BasicPolymorphicTypeValidator.builder().build();
objectMapper.activateDefaultTyping(ptv, ObjectMapper.DefaultTyping.EVERYTHING);

MyClass1 myClass1 = new MyClass1();
myClass1.setSomething("something");

String json = objectMapper.writeValueAsString(myClass1);

MyInterface myInterface = objectMapper.readValue(json, MyInterface.class);

现在的异常(exception)是:

com.fasterxml.jackson.databind.exc.InvalidTypeIdException: Could not resolve type id 'org.something.MyClass1' as a subtype of `org.something.MyInterface`: Configured `PolymorphicTypeValidator` (of type `com.fasterxml.jackson.databind.jsontype.BasicPolymorphicTypeValidator`) denied resolution
 at [Source: (String)"["org.something.MyClass1",{"something":"something"}]"; line: 1, column: 53]

我该如何解决这个问题?

最佳答案

实际上,我通过像这样配置 ObjectMapper 来让它工作:

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.activateDefaultTyping(new LaissezFaireSubTypeValidator(), ObjectMapper.DefaultTyping.EVERYTHING);

不确定这是否是惯用的方法。

关于java - 使用 Jackson 序列化类时添加类型信息,以便可以使用接口(interface)类型反序列化而不使用注释?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62771128/

相关文章:

java - Spring junit Autowiring 自定义类必须有构造函数本身吗?

json - Swift JSONDecoder typeMismatch 错误

java - 使用 Jackson 解析 json 中的 boolean 值时的额外数据

java - Jackson LocalDate 不存在的日期

java - Swing 中展开的 float 复选框

java - 消失时可调整大小的布局 Swing JPanel

c# - 如何将 .NET Core API 配置为始终返回 JSON

java - Jackson TypeReference 在扩展时是否有效?

java - 将 Json 解析为包含对象的对象

java - 通过自定义渲染突出显示 JTable 中的行选择