opeled
opeled

Reputation: 153

jackson serialization views: nested object

The following is a snippet from a project based on Spring Boot 1.3. Json serialization is made via Jackson 2.6.3.

I have the following Spring MVC controller:

@RequestMapping(value = "/endpoint", method = RequestMethod.GET, produces=MediaType.APPLICATION_JSON_VALUE)
public Results<Account> getAllAccounts() throws Exception {
    return service.getAllAccounts();
}

The returned Results is as follows (getters and setters removed):

public class APIResults<T> {
    private Collection<T> data;
}

The Account class is as follows (getters and setters removed):

public class Account {
    @JsonView(Views.ViewA.class)
    private Long id;

    @JsonView(Views.ViewB.class)
    private String name;

    private String innerName;
}

I also have the following Json Views

public class Views {
    public interface ViewA {}
    public interface Publisher extends ViewB {}
}


The motive is to return different view from the same controller, based on some predict.
So I'm using AbstractMappingJacksonResponseBodyAdvice to set the view at run-time. When setting bodyContainer.setSerializationView(Views.ViewA.class), I'm getting an empty json result and not a json array of objects that only contains the id property.
I suspect this is because the data property in APIResults< T > is not annotated with @JsonView, however shouldn't non annotated properties be included in all views (doc)?
Is there a way to get what i want without adding the @JsonView annotation to APIResults< T > (this is not an option).
I know i can use Jackson mixin to get the functionality i desire, however is there a way to do that using Json views ?

Upvotes: 0

Views: 2295

Answers (1)

Eugene
Eugene

Reputation: 2701

You were right, spring MVC Jackson2ObjectMapperBuilder has been improved to set jackson mapper feature DEFAULT_VIEW_INCLUSION to false, so not annotated property data is not serialized.

To enable the feature, use following config (XML):

<mvc:annotation-driven>
    <mvc:message-converters>
        <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
            <property name="objectMapper">
                 <bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
                   <property name="defaultViewInclusion" value="true"/>
                 </bean>
            </property>
        </bean>
    </mvc:message-converters>
</mvc:annotation-driven>

With this config, you'll have id and innerName properties serialized when using ViewA view:

{"data":[
  {"id":1,"innerName":"one"},
  {"id":2,"innerName":"two"},
  {"id":3,"innerName":"three"}
]}

Further, you may manage to hide innerName also, by adding some other view annotation to it.

Upvotes: 1

Related Questions