Custom Jackson JSON serialization based on parent context

I am trying to conditionally serialize a child bean based on information from the parent.

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

public class Child {
  String someValue;
}

      

Basically, if parent.isSecure is true, then I want to serialize someValue differently than if parent.isSecure is false.

My actual classes are much more complex than this simple example, so I really don't want to create a complete custom serializer for the parent that I will need to maintain separately (unless you can show me how to use the standard serializer for the parent in the custom serializer without having to repeat everything properties and handle json annotations, views, etc. If possible this might work as I can set the context attribute based on isSecure).

I don't mind writing a custom serializer for the child, but I don't know how to check the value from the parent.

I considered using a "safe" view and a "unsafe" view, which I could specify outside of the entire serialization process, but then I would have to go through and comment out many properties of the parent class as in both the "safe" and "unsafe" view (since I disabled parameter DEFAULT_VIEW_INCLUSION due to a number of properties that I never want to serialize).

I tried to access the generator .getCurrentValue () in my custom child serializer, but it is always zero, so I'm not sure how it should work.

I considered creating a custom serializer for isSecure and setting the context attribute on it, but how can I be sure it will be called before the custom serializer for the child? (Though I'll admit I'm not sure if the context attributes actually work the way I assume.)

Any ideas?

+3


source to share


2 answers


You can create a serializer specific to your scenario isSecure

. Using JsonGenerator#getCurrentValue

inside a child returns the parent. Something like this should allow you to control serialization Child

without changing the serialization of other properties to Parent

.

Create a serializer Child

to check the propertyParent

SecureChildSerializer

and InsecureChildSerializer

are designed to implementJsonSerializer<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);
            }
        }
    }
}

      

Apply Serializer Child

to Properties of Concern

public class Parent {
    public boolean isSecure;

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

      

+2


source


I don't know the full length of your design, but IMHO I think this suggests some kind of design problem. If objects are parsed differently, this means that they are significantly different from each other - in that case, why not separate them by inheritance? One of the methods:



    public class Parent {
        private Child child;
    }

    public class SecureChild extends Parent {
        String someValue;
    }

    public class InSecureChild extends Parent {
        String someValue;
    }

      

0


source







All Articles