8

I am using the following bean definition to make my spring app talking in JSON

<bean id="jacksonMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" />

Is it possible with this message converter bean to use the @JsonView annotation?

Georgios Syngouroglou
  • 18,813
  • 9
  • 90
  • 92
Erik
  • 11,944
  • 18
  • 87
  • 126

2 Answers2

18

@JsonView is already supported in the Jackson JSON Processor from v1.4 onwards.

New Edit: Updated for Jackson 1.9.12

According to the v1.8.4 documentation the function I was using writeValueUsingView is now Deprecated Use ObjectMapper.viewWriter(java.lang.Class) instead… however that has also been Deprecated Since 1.9, use writerWithView(Class) instead! (see v1.9.9 documentation)

So here is an updated example, tested with Spring 3.2.0 and Jackson 1.9.12 which simply returns {id: 1} and not the extended {name: "name"} since it is using the .writerWithView(Views.Public.class). Switching to Views.ExtendPublic.class will result in {"id":1,"name":"name"}

package com.demo.app;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import org.codehaus.jackson.map.annotate.JsonView;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.ObjectWriter;

import javax.servlet.http.HttpServletResponse;

import java.io.IOException;

@Controller
public class DemoController {
    private final ObjectMapper objectMapper = new ObjectMapper();

    @RequestMapping(value="/jsonOutput")
    @ResponseBody
    public String myObject(HttpServletResponse response) throws IOException {
        ObjectWriter objectWriter = objectMapper.writerWithView(Views.Public.class);
        return objectWriter.writeValueAsString(new MyObject());
    }

    public static class Views {
        static class Public {}
        static class ExtendPublic extends Public {}
    }

    public class MyObject {
        @JsonView(Views.Public.class) Integer id = 1;
        @JsonView(Views.ExtendPublic.class) String name = "name";
    }
}

Previous Edit: You need to instantiate the ObjectMapper and write out the object using a custom view as shown here, or in this example:

Define views:

class Views {
    static class Public {}
    static class ExtendedPublic extends PublicView {}
    ...
}

public class Thing {
    @JsonView(Views.Public.class) Integer id;
    @JsonView(Views.ExtendPublic.class) String name;
}

Use views:

private final ObjectMapper objectMapper = new ObjectMapper();

@RequestMapping(value = "/thing/{id}")
public void getThing(@PathVariable final String id, HttpServletResponse response) {
    Thing thing = new Thing();
    objectMapper.writeValueUsingView(response.getWriter(), thing, Views.ExtendPublic.class);
}

If you are using Jackson >= 1.7 you might find that the @JSONFilter better suits your needs.

andyb
  • 43,435
  • 12
  • 121
  • 150
  • Yes, but how does the Mapper know which view to render? – Erik Apr 26 '11 at 09:41
  • I don't think the mapper can know. You have to write the object yourself. I've edited my answer but also added a link to the `@JSONFilter` which might be better for you. Since the example in my answer will always write JSON formatted output. If you need to support other output formats this will not work for you. – andyb Apr 26 '11 at 10:06
  • 1
    Please, vote for it to be a new feature: https://jira.springsource.org/browse/SPR-7156?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel – Filip Spiridonov Mar 20 '13 at 11:31
  • 1
    @Premier More information is required before I can even attempt to help you. Which part is not working? Which version of Jackson are you using? What _exactly_ is your problem? – andyb Apr 12 '13 at 13:23
  • I'm using Jackson JSON 1.9.12 with SpringMVC. I've created a dto with json fieds. I want two profile of same dto with different fields, so i created two interfaces and i've annontated fields with @JsonView annotation. In controller i've used your code with objectmapper to write dto in json string, but no filter is applyed, all fields are inserted in json string. – Premier Apr 12 '13 at 13:45
  • Which version of Spring? I am just trying to create a fully working demo to see if anything has changed since I wrote the answer. – andyb Apr 12 '13 at 14:17
  • @Premier I have added an updated example which is working for me – andyb Apr 12 '13 at 14:54
8

@JsonView annotation was not supported on Spring but this issue is solved!
Follow this

Add support for Jackson serialization views

Spring MVC now supports Jackon's serialization views for rendering different subsets of the same POJO from different controller methods (e.g. detailed page vs summary view). Issue: SPR-7156

This is the SPR-7156.

Status: Resolved

Description

Jackson's JSONView annotation allows the developer to control which aspects of a method are serialiazed. With the current implementation, the Jackson view writer must be used but then the content type is not available. It would be better if as part of the RequestBody annotation, a JSONView could be specified.

Available on Spring ver >= 4.1

Thank you Spring!

Georgios Syngouroglou
  • 18,813
  • 9
  • 90
  • 92