【问题标题】:Using @JsonView with Spring MVC在 Spring MVC 中使用 @JsonView
【发布时间】:2011-08-11 22:52:38
【问题描述】:

我正在使用以下 bean 定义来使我的 spring 应用程序以 JSON 方式进行对话

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

这个消息转换器bean是否可以使用@JsonView注解?

【问题讨论】:

  • 仅供参考,我终于写出了自己的观点

标签: java json spring spring-mvc jakarta-ee


【解决方案1】:

Spring 不支持@JsonView 注解,但是这个问题已经解决了!
关注this

添加对 Jackson 序列化视图的支持

Spring MVC 现在支持 Jackon 的序列化视图进行渲染 来自不同控制器的相同 POJO 的不同子集 方法(例如详细页面与摘要视图)。 问题:SPR-7156

这是SPR-7156

状态:已解决

说明

Jackson 的 JSONView 注释允许开发人员控制方法的哪些方面被序列化。对于当前的实现,必须使用 Jackson 视图编写器,但内容类型不可用。如果作为 RequestBody 注释的一部分,可以指定 JSONView 会更好。

可在Spring ver >= 4.1

谢谢春天!

【讨论】:

    【解决方案2】:

    @JsonView 从 v1.4 开始在 Jackson JSON 处理器中为 already supported

    新编辑:为 Jackson 1.9.12 更新

    根据 v1.8.4 documentation,我使用的函数 writeValueUsingView 现在已弃用 改用 ObjectMapper.viewWriter(java.lang.Class)...但是,这也已弃用 从 1.9 开始,请改用 writerWithView(Class)! (见 v1.9.9 documentation

    所以这是一个更新的示例,使用 Spring 3.2.0 和 Jackson 1.9.12 进行测试,它只返回 {id: 1} 而不是扩展的 {name: "name"},因为它使用的是 .writerWithView(Views.Public.class)。切换到Views.ExtendPublic.class 将导致{"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";
        }
    }
    

    以前的编辑:您需要实例化 ObjectMapper 并使用自定义视图写出对象,如 here 所示,或者在本例中:

    定义视图:

    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;
    }
    

    使用视图:

    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);
    }
    

    如果您使用的是 Jackson >= 1.7,您可能会发现 @JSONFilter 更适合您的需求。

    【讨论】:

    • 是的,但是 Mapper 如何知道要渲染哪个视图?
    • 我不认为映射器可以知道。您必须自己编写对象。我已经编辑了我的答案,但还添加了一个指向 @JSONFilter 的链接,这可能对你更好。由于我的答案中的示例将始终编写 JSON 格式的输出。如果您需要支持其他输出格式,这将不适合您。
    • 请投票支持它成为新功能:jira.springsource.org/browse/…
    • @Premier 需要更多信息才能帮助您。哪个部分不工作?你用的是哪个版本的杰克逊? 究竟你的问题是什么?
    • 我将 Jackson JSON 1.9.12 与 SpringMVC 一起使用。我用 json 字段创建了一个 dto。我想要两个具有不同字段的相同 dto 配置文件,所以我创建了两个接口,并使用 @JsonView 注释对字段进行了注释。在控制器中,我使用您的代码和 objectmapper 在 json 字符串中写入 dto,但没有应用过滤器,所有字段都插入到 json 字符串中。
    猜你喜欢
    • 2015-10-30
    • 2015-07-25
    • 2014-07-03
    • 1970-01-01
    • 1970-01-01
    • 2015-05-06
    • 1970-01-01
    • 2015-12-06
    • 2020-07-03
    相关资源
    最近更新 更多