Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using @JsonView with Spring MVC

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?

like image 263
Erik Avatar asked Apr 24 '11 18:04

Erik


People also ask

What is the use of @JsonView?

@JsonView is used to control values to be serialized or not.

What is default_ view_ INCLUSION?

DEFAULT_VIEW_INCLUSION. Feature that determines whether properties that have no view annotations are included in JSON serialization views (see JsonView for more details on JSON Views).

What is Jackson in spring boot?

Jackson. Jackson is a suite of data-processing tools for Java. It allows to read and write data in JSON, Avro, BSON, CBOR, CSV, Smile, (Java) Properties, Protobuf, XML or YAML format. Jackson is auto-configured. It comes with the spring-boot-starter-json .

What are JSON views?

A JSON view is one of the predefined view types that are available in SAPUI5. The JSON view type is defined in a file. The file name has to either end with . view. json or as a JSON string.


1 Answers

@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.

like image 111
andyb Avatar answered Oct 12 '22 11:10

andyb