How to get the list of properties of a class as Jackson views it?

Joffrey :

I'm writing code that needs to access the list of properties of a class as defined by a Jackson configuration.

For instance, for the following class:

@JsonIgnoreProperties(value = { "intValue" })
public class MyDto {

    @JsonProperty("name")
    private String stringValue;

    private int intValue;

    private long longValue;

    @JsonIgnore
    private boolean booleanValue;

    // standard setters and getters are not shown
}

I would get [name,longValue] because that's the properties that Jackson actually considers when serializing.

I don't think writing a whole piece of code to look for getters/setters and inspect Jackson annotations is the way to go, since that would be reimplementing Jackson.

If I'm able to get a handle on the Jackson ObjectMapper used for serialization, is there a way to get a list of properties of a Class<?> or Type object? (respecting Jackson annotations and config)

I dug a bit into Jackson's implementation, and found the POJOPropertiesCollector, but I'm not sure about how I can use it from outside Jackson (we're not supposed to do this I believe).

As a last resort, I could create an instance of the class I'm inspecting, serialize it with the ObjectMapper, and then parse the JSON to find property names, but I don't think this is clean either (and it would bring its whole set of probelms: nulls might not be serialized, what happens in the construtor etc.).

Any ideas?

cassiomolin :

With Jackson, you can introspect an arbitrary class to get the available JSON properties:

// Construct a Jackson JavaType for your class
JavaType javaType = mapper.getTypeFactory().constructType(MyDto.class);

// Introspect the given type
BeanDescription beanDescription = mapper.getSerializationConfig().introspect(javaType);

// Find properties
List<BeanPropertyDefinition> properties = beanDescription.findProperties();

The BeanPropertyDefinition list should give you the details you need regarding the JSON properties.


The @JsonIgnoreProperties class level annotation is not taken into account with the above mentioned approach. But you can use an AnnotationIntrospector to get the properties ignored on class level:

// Get class level ignored properties
Set<String> ignoredProperties = mapper.getSerializationConfig().getAnnotationIntrospector()
        .findPropertyIgnorals(beanDescription.getClassInfo()).getIgnored();

Then filter properties removing the properties which are present in ignoredProperties:

// Filter properties removing the class level ignored ones
List<BeanPropertyDefinition> availableProperties = properties.stream()
        .filter(property -> !ignoredProperties.contains(property.getName()))
        .collect(Collectors.toList());

This approach works even if you have mix-ins defined for your class.


The AnnotationIntrospector#findPropertyIgnorals(Annotated) method was introduced in Jackson 2.8. The AnnotationIntrospector#findPropertiesToIgnore(Annotated, boolean) method can be used for older versions (but it's deprecated since Jackson 2.8).

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=444630&siteId=1