Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to control Jackson serialization of a library class

I have a class (let us call it a Piece) containing a member of type com.jme3.math.ColorRGBA. With a default Jackson serialization the member is serialized not only as its members r, g, b and a, but then also using getters like getAlpha.

As this is obviously redundant, I would like to control the serialization and to serialize only those primary members. Are there some annotations that I can write to my class to control serialization of members with types not under my control, or some custom serializers for them?

I can probably write a custom serializer for the Piece class, though other than ColorRGBA serializer being too verbose, default serialization works fine for me for all other properties of Piece, therefore I would like to customize as little of it as possible.

I do not want to modify jme3 library source, the solution should be implemented outside of the ColorRGBA class.

like image 422
Suma Avatar asked Jan 27 '15 14:01

Suma


People also ask

Does Jackson use Java serialization?

Note that Jackson does not use java. io. Serializable for anything: there is no real value for adding that. It gets ignored.

What is ObjectMapper class in Jackson?

ObjectMapper is the main actor class of Jackson library. ObjectMapper class ObjectMapper provides functionality for reading and writing JSON, either to and from basic POJOs (Plain Old Java Objects), or to and from a general-purpose JSON Tree Model (JsonNode), as well as related functionality for performing conversions.

Does Jackson serialize methods?

Let's start with the default behavior of Jackson regarding private fields. Jackson can't serialize private fields - without accessor methods - with its default settings.

Is Jackson serialized?

Jackson is a solid and mature JSON serialization/deserialization library for Java. The ObjectMapper API provides a straightforward way to parse and generate JSON response objects with a lot of flexibility.


2 Answers

You can use a mixin to make sure that the class is serialized as per your needs. Consider the following:

// The source class (where you do not own the source code)
public class ColorRGBA {
    public float a; // <-- Want to skip this one
    public float b;
    public float g;
    public float r;
}

Then, create the mixin where you ignore the a property.

// Create a mixin where you ignore the "a" property
@JsonIgnoreProperties("a")
public abstract class RGBMixin {
    // Other settings if required such as @JsonProperty on abstract methods.
}

Lastly, configure your mapper with the mixin:

ObjectMapper mapper = new ObjectMapper();
mapper.addMixInAnnotations(ColorRGBA.class, RGBMixin.class);
System.out.println(mapper.writeValueAsString(new ColorRGBA()));

The output will be:

{"b":0.0,"g":0.0,"r":0.0}

Note that the method ObjectMapper.addMixInAnnotations is deprecated from Jackson 2.5 and should be replaced with the more fluent version:

mapper.addMixIn(ColorRGBA.class, RGBMixin.class);

The JavaDocs can be found here

like image 130
wassgren Avatar answered Nov 03 '22 01:11

wassgren


Option A

If you control the source of the class, can put this above class:

@JsonAutoDetect(fieldVisibility = Visibility.ANY, getterVisibility = Visibility.NONE, setterVisibility = Visibility.NONE)
public class ColorRGBA {

Option B

Otherwise you can set up an object mapper to ignore getters:

ObjectMapper mapper = new ObjectMapper();
mapper.setVisibilityChecker(mapper.getSerializationConfig().getDefaultVisibilityChecker()
                .withFieldVisibility(JsonAutoDetect.Visibility.ANY)
                .withGetterVisibility(JsonAutoDetect.Visibility.NONE)
                .withSetterVisibility(JsonAutoDetect.Visibility.NONE)
                .withCreatorVisibility(JsonAutoDetect.Visibility.NONE));

mapper.writeValue(stream, yourObject);

Option C

For more complicated requirements, you can write your own VisibilityChecker implementation.

like image 32
weston Avatar answered Nov 02 '22 23:11

weston