Reputation: 12140
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?
Upvotes: 8
Views: 34040
Reputation: 20004
@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!
Upvotes: 8
Reputation: 43823
@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.
Upvotes: 18