digitaljoel
digitaljoel

Reputation: 26574

Jackson JsonView not being applied

Jackson 2.2.2

ObjectMapper mapper = new ObjectMapper();
mapper.getSerializationConfig().withView(Views.Public.class);
mapper.configure(MapperFeature.DEFAULT_VIEW_INCLUSION, false);
// if I try to simply configure using .without that config feature doesn't get set.
// I MUST use the .configure as above, but I guess that's a different question.
//        .without(MapperFeature.DEFAULT_VIEW_INCLUSION);

// this first one doesn't have the view applied.
String result = mapper.writeValueAsString(savedD);

// this second one works.
result = mapper.writerWithView(Views.Public.class).writeValueAsString(savedD);

I would expect this configuration, were I set the view on the SerializationConfig, to be applied to all Objects that are mapped with this ObjectMapper.

How can I make an ObjectMapper always apply a JsonView without having to call writerWithView so that I can just give this ObjectMapper to Spring MVC?

Upvotes: 2

Views: 5052

Answers (1)

digitaljoel
digitaljoel

Reputation: 26574

Turns out if you actually read the docs you find out that you can't just change serialization configuration by calling getSerializationConfig and calling setters on it.

/**
 * Method that returns the shared default {@link SerializationConfig}
 * object that defines configuration settings for serialization.
 *<p>
 * Note that since instances are immutable, you can NOT change settings
 * by accessing an instance and calling methods: this will simply create
 * new instance of config object.
 */
SerializationConfig getSerializationConfig();

I repeat, you can NOT change settings by accessing an instance and calling methods:

So you must call the .configure method instead of .without and you cannot set the view by calling .withView. Those methods will construct a new instance of SerializationConfig, but there is no way to get your new SerializationConfig back into the ObjectMapper.

In order to get around that and wire my ObjectMapper up to be used by Spring MVC when it processes a @ResponseBody I implemented the following:

  @Configuration
  class WebConfig extends WebMvcConfigurerAdapter {
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
      MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
      ObjectMapper mapper = new ObjectMapper() {
        private static final long serialVersionUID = 1L;
        @Override
        protected DefaultSerializerProvider _serializerProvider(SerializationConfig config) {
          // replace the configuration with my modified configuration.
          // calling "withView" should keep previous config and just add my changes.
          return super._serializerProvider(config.withView(Views.Public.class));
        }        
      };
      mapper.configure(MapperFeature.DEFAULT_VIEW_INCLUSION, false);
      converter.setObjectMapper(mapper);
      converters.add(converter);
    }
  }

With all that in place, everything is working for me.

Upvotes: 1

Related Questions