基于父上下文的自定义Jackson JSON序列化

时间:2015-06-24 19:02:16

标签: java json serialization jackson

我试图根据来自父级的信息有条件地序列化一个子bean。

public class Parent {
  private boolean isSecure;
  private Child child;
}

public class Child {
  String someValue;
}

基本上,如果parent.isSecure为true,那么我想以不同于parent.isSecure为假的方式序列化someValue。

我的实际类比这个简单的例子复杂得多,所以我真的不想为Parent创建一个完整的自定义序列化器,我需要单独维护(除非你能告诉我如何利用Parent的标准序列化)在自定义序列化程序中,无需遍历所有属性并处理json注释,视图等。如果可以,这可能会起作用,因为我可以基于isSecure设置上下文属性。)

我不介意为孩子编写自定义序列化程序,但我不知道如何检查父项的值。

我考虑过使用'安全'视图和'不安全'视图,我可以在整个序列化过程之外指定,但是我必须经历并注释父类的许多属性都在'安全'和'不安全'视图(因为我已经关闭了DEFAULT_VIEW_INCLUSION选项,因为我从不想要序列化许多属性)。

我试图在我的自定义子序列化程序中访问generator.getCurrentValue(),但它总是为null,所以我不确定它应该如何工作。

我考虑过为isSecure编写一个自定义序列化程序,并在其中设置一个上下文属性,但是我怎么能确定它会在子程序的自定义序列化程序之前被调用? (虽然我承认我不确定上下文属性是否真的像我假设的那样。)

有什么想法吗?

2 个答案:

答案 0 :(得分:2)

您可以创建特定于isSecure方案的序列化程序。在子元素内使用JsonGenerator#getCurrentValue将返回父元素。这样的事情应该允许您控制Child的序列化,而不必修改Parent上其他属性的序列化。

创建Child序列化程序以检查Parent属性

SecureChildSerializerInsecureChildSerializer旨在实现JsonSerializer<Child>

public class IsSecureChildSerializer extends JsonSerializer<Child> {
    private static final SecureChildSerializer SECURE_CHILD_SERIALIZER = new SecureChildSerializer();
    private static final InsecureChildSerializer INSECURE_CHILD_SERIALIZER = new InsecureChildSerializer();

    @Override
    public void serialize(Child value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        if (gen.getCurrentValue() instanceof Parent) {
            Parent parent = (Parent) gen.getCurrentValue();
            if (parent.isSecure) {
                SECURE_CHILD_SERIALIZER.serialize(value, gen, serializers);
            } else {
                INSECURE_CHILD_SERIALIZER.serialize(value, gen, serializers);
            }
        }
    }
}

Child序列化程序应用于关注的属性

public class Parent {
    public boolean isSecure;

    @JsonSerialize(using = IsSecureChildSerializer.class)
    public Child child;
}

答案 1 :(得分:0)

我不知道您的设计的全长,但恕我直言,我认为这表明设计中存在一些问题。如果对象的解析方式不同,则意味着它们本质上是不同的 - 在这种情况下,为什么不通过继承将它们分开?一种方法是:

    public class Parent {
        private Child child;
    }

    public class SecureChild extends Parent {
        String someValue;
    }

    public class InSecureChild extends Parent {
        String someValue;
    }