7

Ideally, it would look much like this:

List<String> props = objectMapper.getKnownProperties(MyPojo.class);

Alas, there is no such method. An approach that would generally work is to explicitly set Include.ALWAYS as the ObjectMapper's default, instantiate an instance of the class reflectively, convert it to a map, and examine the keyset. However, classes can still override the ObjectMapper's include behavior given annotations.

Is there a more elegant approach? At the very least, is there a way to override class annotations using the object mapper?

Edit:
Just to clarify, these pojos/javabeans/DTOs are designed for use with Jackson and are already rigged with annotations to result in specific serialization behavior. It just so happens that I need to dynamically know what I might end up with up-front, ideally without duplicating the information already available to jackson. That said, if another framework offers this functionality, I'd be curious to know. :)

Shaun
  • 2,490
  • 6
  • 30
  • 39
  • 1
    What are you trying to do, exactly? Maybe there's a better tool for the job. – dnault Sep 23 '13 at 05:40
  • Have you tried Gson? Then you don't need to know all the properties in order to convert to and from json. – Jan Vladimir Mostert Sep 23 '13 at 05:44
  • 1
    Specifically, I'm developing a small rest api framework that allows html clients to sort/search based on any json property that corresponds to a singular attribute of the JPA data model. In order to properly construct the query up-front, I need this information to determine the valid possibilities. – Shaun Sep 23 '13 at 09:26

4 Answers4

7

With Jackson, you can introspect a class and get the available JSON properties using:

// 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();

If you have @JsonIgnoreProperties class level annotations, check this answer.

cassiomolin
  • 124,154
  • 35
  • 280
  • 359
2

Depending on your exact needs, JsonFilter could also work (f.ex see http://www.cowtowncoder.com/blog/archives/2011/09/entry_461.html).

And for more advanced cases, BeanSerializerModifier does give you access to actual list of BeanPropertyWriters, which represent individual properties POJO has. From that, you could write a wrapper that enables/disables output dynamically. Or perhaps you can even combine approaches: modifier to get list of possible property names; then FilterProvider to dynamically add filter. Benefit of this would be that it is a very efficient way of implementing filtering.

StaxMan
  • 113,358
  • 34
  • 211
  • 239
1

It's possible to ignore all annotations by using a dummy AnnotationIntrospector:

objectMapper.setAnnotationIntrospector(new AnnotationIntrospector(){
    @Override public Version version() {
        return Version.unknownVersion();
    }
});
dnault
  • 8,340
  • 1
  • 34
  • 53
  • Thanks for the breadcrumb. I wouldn't want to ignore all annotations (the effect of `@JsonProperty` and `@JsonIgnore` is pretty fundamental), but ignoring `@JsonInclude` ensures that all potential attributes are serialized. It looks like `AnnotationIntrospector.findSerializationInclusion()` is the thing to override (or perhaps proxy). – Shaun Sep 23 '13 at 09:48
  • To suppress specific annotations, you can subclass `JacksonAnnotationIntrospector`, override methods that handle relevant annotations. – StaxMan Sep 25 '13 at 17:41
1

Perhaps you could use Jackson's JSON Schema module to generate a schema for a class, then inspect the schema.

dnault
  • 8,340
  • 1
  • 34
  • 53