secureboot
secureboot

Reputation: 1885

Polymorphic deserialization in Jackson based on ints, not strings

Normally, when doing polymorphic deserialization with Jackson, I have a string field that maps to a class, and can do it like this.

@JsonTypeInfo(
    use = JsonTypeInfo.Id.NAME,
    include = JsonTypeInfo.As.PROPERTY,
    property = "methodName")
@JsonSubTypes({
    @JsonSubTypes.Type(value = MyFirstClass.class, name = "firstClassName"),
    @JsonSubTypes.Type(value = MySecondClass.class, name = "secondClassName")}) 

I can't find any easy example of how to do this if the value is an integer, rather than a string. For instance, how would I pick which class to deserialize into if instead of "methodName":"firstClassName" my JSON included "methodName":1?

Upvotes: 2

Views: 351

Answers (2)

M. Justin
M. Justin

Reputation: 21114

If you're just concerned with deserialization, you can set the value of the name element of @JsonSubTypes.Type to the string representation of the integer. This will properly deserialize from a number value in the JSON. However, when serializing, it will serialize into the string representation of that value rather than as a number (e.g. "1" instead of 1).

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "methodName")
@JsonSubTypes({
        @JsonSubTypes.Type(value = MyFirstClass.class, name = "1"),
        @JsonSubTypes.Type(value = MySecondClass.class, name = "2")})

Alternatively, you can make it serialize and deserialize into a number instead of a string with a bit more boilerplate code, if you're willing to add a method for that value duplicating the value declarations from @JsonSubTypes.Type:

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "methodName", include = JsonTypeInfo.As.EXISTING_PROPERTY)
@JsonSubTypes({
        @JsonSubTypes.Type(value = MyFirstClass.class, name = "1"),
        @JsonSubTypes.Type(value = MySecondClass.class, name = "2")})
public static abstract class Superclass {
    public abstract int getMethodName();
}

public static class MyFirstClass extends Superclass {
    @Override
    public int getMethodName() {
        return 1;
    }
}

public static class MySecondClass extends Superclass {
    @Override
    public int getMethodName() {
        return 2;
    }
}

Upvotes: 1

Nikola Yovchev
Nikola Yovchev

Reputation: 10216

There is no 'easy' way of doing that. You have to write your own implementation of the serialization mechanicsm, and one for the deserialization. The perils of such implementation are so many that you'd be better off just quoting your typeinfo property and using it as a String.

Upvotes: 1

Related Questions