我的用例是使用@ResponseBody注释的典型控制器映射,直接返回特定对象或对象集合,然后当客户端将Accept / json添加到Accept标头时,将其与JacksonJson呈现.
我有两个答案,第一个建议使用不同的getter列表返回不同的接口,第二个建议使用Json Views.
我没有理解第一种方法的问题,但是,第二种方法,在阅读了JacksonJsonViews
的文档之后,我不知道如何使用Spring来实现它.
为了保持这个例子,我将在类中声明三个stub类视图:
// View definitions: public class Views { public static class Public { } public static class ExtendedPublic extends PublicView { } public static class Internal extends ExtendedPublicView { } }
然后我要声明提到的类:
public class PublicView { } public class ExtendedPublicView { }
为什么他们宣布空静态类和外部空类,我不知道.我明白他们需要一个“标签”,但是静态的观点就足够了.而扩展公开不是扩展公众的,因为它是合乎逻辑的,但它们实际上是完全无关的.
最后,bean将使用注释指定视图或视图列表:
//changed other classes to String for simplicity and fixed typo //in classname,the values are hardcoded,just for testing public class Bean { // Name is public @JsonView(Views.Public.class) String name = "just testing"; // Address semi-public @JsonView(Views.ExtendedPublic.class) String address = "address"; // SSN only for internal usage @JsonView(Views.Internal.class) String ssn = "32342342"; }
最后在Spring Controller中,我必须考虑如何更改我的测试bean的原始映射:
@RequestMapping(value = "/bean") @ResponseBody public final Bean getBean() { return new Bean(); }
它说:
//or,starting with 1.5,more convenient (ObjectWriter is reusable too) objectMapper.viewWriter(ViewsPublic.class).writeValue(out,beanInstance);
所以我有一个ObjectMapper实例从无处出来,而不是servlet典型的PrintWriter out = response.getWriter();而是一个JsonGenerator的实例,并且不能用新的运算符获得.所以我不知道如何修改方法,这里是一个不完整的尝试:
@RequestMapping(value = "/bean") @ResponseBody public final Bean getBean() throws JsonGenerationException,JsonMappingException,IOException { ObjectMapper objectMapper = new ObjectMapper(); JsonGenerator out; //how to create? objectMapper.viewWriter(Views.Public.class).writeValue(out,new Bean()); return ??; //what should I return? }
所以我想知道有没有人有成功使用JsonView与Spring和他/她做了什么.整个概念似乎很有趣,但文档似乎很缺乏,代码示例也不见了.
如果不可能,我将只使用扩展对方的接口.对不起,长期的问题.
解决方法
@Controller public class BookService { @RequestMapping("/books") @ResponseView(SummaryView.class) public @ResponseBody List<Book> getBookSummaries() {} @RequestMapping("/books/{bookId}") public @ResponseBody Book getBook(@PathVariable("bookId") Long BookId) {} }
其中SummaryView在Book模型上注释如下:
@Data class Book extends BaseEntity { @JsonView(SummaryView.class) private String title; @JsonView(SummaryView.class) private String author; private String review; public static interface SummaryView extends BaseView {} } @Data public class BaseEntity { @JsonView(BaseView.class) private Long id; } public interface BaseView {}
然后将自定义HandlerMethodReturnValueHandler连接到Spring MVC的上下文中以检测@ResponseView注释,并相应地应用Jackson视图.
我提供了完整的代码over on my blog.