【问题标题】:How to add custom deserializer to interface using jackson如何使用杰克逊将自定义解串器添加到接口
【发布时间】:2014-10-12 19:44:56
【问题描述】:

假设我有一个接口 A,我想为所有实现接口 A 的类使用自定义反序列化器,所以我使用下面的代码但它不起作用,而 CustomAserializer 工作。 那么我应该怎么做才能使用我的自定义反序列化器反序列化所有实现 A 的类。 谢谢。

module.addDeserializer(A.class, new CustomADeserializer());
module.addSerializer(A.class, new CustomASerializer())

【问题讨论】:

  • 它应该可以工作。你使用的是哪个版本的Jackson
  • @MichałZiober jackson 1.9.13 with jersey 2.6,序列化器没问题,但反序列化器不起作用。
  • 我用Jackson 2.4检查了它,它工作正常。

标签: java json serialization jackson deserialization


【解决方案1】:

您似乎忘记用 @JsonDeserialize(using = ImplementationClazz.class) 注释您的实现类,以表明该类应该用于反序列化抽象类或接口。

以下是使用 Jackson 反序列化具有多个实现的接口的简单示例。

这是我的界面:

@JsonDeserialize(using = UserDeserializer.class)
public interface User {
}

接口的一种实现:

@JsonDeserialize(as = ServiceUser.class)
public class ServiceUser implements User{

    private String name;
    private String role;

    //constructor, setters & getters

第二次实施:

@JsonDeserialize(as = AdminUser.class)
public class AdminUser implements User {

    private String role;
    private String designation;

    //constructor, setters & getters

这里是反序列化器:

public class UserDeserializer extends JsonDeserializer<User> {
    @Override
    public User deserialize(JsonParser jp, DeserializationContext context) throws IOException {
        ObjectMapper mapper = (ObjectMapper) jp.getCodec();
        ObjectNode root = mapper.readTree(jp);

        /*write your own condition*/
        if (root.has("name") && root.get("name").asText().equals("XYZ")) {
            return mapper.readValue(root.toString(), ServiceUser.class);
        }
        return mapper.readValue(root.toString(), AdminUser.class);
    }
}

如果您不对实现类进行注释,您可能会收到 StackOverflowError。所有实现类都应该反序列化自己,否则它将使用父类中的反序列化器,这会导致 StackOverflowError。

【讨论】:

  • 完美!这就是我要找的。​​span>
  • 这适用于简单的情况,但是如果您有一个可以包含各种子类的嵌套项目列表,这将不起作用。为此,您必须将 JsonCreator 与上述解决方案一起使用。
【解决方案2】:

以防万一有人需要一种解决方案来序列化和去除继承层次结构

您可以更优雅地使用杰克逊注解:JsonTypeInfoJsonSubTypes

 @JsonTypeInfo(
  use = JsonTypeInfo.Id.NAME, 
  include = JsonTypeInfo.As.PROPERTY, 
  property = "type")
@JsonSubTypes({ 
  @Type(value = ServiceUser.class, name = "service"), 
  @Type(value = AdminUser.class, name = "admin") 
})
public interface User{
    // ...
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-04-26
    • 2019-10-24
    • 2021-05-31
    • 1970-01-01
    • 2019-05-25
    • 2013-02-21
    • 2018-02-10
    • 1970-01-01
    相关资源
    最近更新 更多