Jackson Json Views with DropWizard

On my current project we've been using DropWizard. For the most part this experience has been pleasant, of course it hasn't been without it's challenges but software development is never without challenges. The most recent challenge has been using Jackson's JsonViews.

Due to the domain we're working in we have few models that contain many fields, while we could split these into multiple models it seems unnecessary at this point in time. We're talking 10-15 fields, so not massive but definitely large. This means that at times we don't want to serialise the entire model, one example of this is when we're listing models. The list of models don't need all of the fields, just 4 of the fields in our case. Jackson's JsonViews appeared to be the solution to this problem and you can find the wiki page about them here.

The first problem I encountered was that the views didn't appear to be working as they should. Our models make use of the defaults for JsonAutodetect, so with the exception of a few `@JsonIgnore` annotations the models are relatively free of annotations. When I first started with JsonViews this became a problem. I added the `@JsonView` annotation to just the id field, this should be the smallest amount of work required to see the Json views working. As an example this is what the model might look like:

public class Person {
    @JsonView(PersonViews.Min.class)
    int id;
    
    String firstName;
    
    String lastName;
}

When we now try to serialise this object using Jackson what you'll see is the entire object serialised. So does this mean JsonViews aren't working? No, I've just overlooked one part of the documentation for JsonViews under the section 'Handling of "view-less" properties'. Due to the fact that the fields `firstName` and  `lastName` don't have any JsonView annotations on them they become "view-less" and by default Jackson will include them in every view.

We have two possible solutions to this problem, the first was the easiest to discover.

If we turn off auto detection for everything Jackson then isn't aware of the fields and won't try to serialise them. However if you want to avoid annotating every field you want outside of the view this isn't going to be a very good solution.

The second is for us to go back and actually read that documentation a little better.... *sigh*.

objectMapper.configure(SerializationConfig.Feature.DEFAULT_VIEW_INCLUSION, false);

But I quickly ran into another snag. I want to serialise this from a DropWizard resource. This means I want to use this so I can add the `@JsonView` annotation to one of my JAX-RS endpoints.... This means I don't have an object mapper to configure... Thankfully DropWizard has us covered (assuming you're ok with changing this globally).

Back in our application class we'll have a method `run` which gives us access to the configuration and environment. DropWizard keeps the object mapper on the environment, so based on the documentations we should be able to add the following line to that `run` method:

environment.getObjectMapper().configure(SerializationConfig.Feature.DEFAULT_VIEW_INCLUSION, false);

But (at least with the versions I have) the API for the ObjectMapper appears to have changed, and instead I used the following:

environment.getObjectMapper().disable(MapperFeature.DEFAULT_VIEW_INCLUSION);

And with that we have our JsonViews working and being served out of our Resource. This might seem pretty obvious to those of you who've spent some time working with Jackson and JAX-RS, however for newbie like myself it wasn't so obvious.

Comments