Bakkenrak
Bakkenrak

Reputation: 143

Jackson serialize class name as property for all objects

I'd like the class name of all POJOs Jackson serializes to JSON objects to be included as a property of the respective object. Ideally, this should be achieved through some general setting of the ObjectMapper or similar.

Serialization example:

public class MyClass {
  private String someField;
  private MyOtherClass anotherField;
}

to

{
  "$type": "MyClass",
  "someField": "abc",
  "anotherField": {
    "$type": "MyOtherClass",
    ...
  }
}

I know this could also be done by annotating all the respective classes with something like

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "$type")

But I'd like to avoid that.

I've also tried

objectMapper.enableDefaultTypingAsProperty(ObjectMapper.DefaultTyping.JAVA_LANG_OBJECT, "$type")

which didn't seem to work.

Is there such a general setting available?


EDIT: Thanks to AZWN's hints I actually got what I was looking for by customizing and constructing a TypeResolverBuilder with DefaultTyping.NON_FINAL.

StdTypeResolverBuilder typer = new ObjectMapper.DefaultTypeResolverBuilder(ObjectMapper.DefaultTyping.NON_FINAL) {
    @Override
    public boolean useForType(JavaType t) {
        return !(t.isCollectionLikeType() || t.isMapLikeType()) && super.useForType(t);
    }
}
        .init(JsonTypeInfo.Id.NAME, null)
        .inclusion(JsonTypeInfo.As.PROPERTY)
        .typeProperty("$type");

objectMapper.setDefaultTyping(typer);

Upvotes: 1

Views: 3772

Answers (1)

AZWN
AZWN

Reputation: 173

You should use ObjectMapper.DefaultTyping.NON_FINAL instead of ObjectMapper.DefaultTyping.JAVA_LANG_OBJECT, since the latter one only includes type properties when the field type of a class is Object at compile time.

For more info, see the docs. Also, be aware of the security issues they mention.

Upvotes: 1

Related Questions