SpringMvc @JsonView 使用方式

准确来说,@JsonView注解不是Spring的,它位于jackson-annotation包中; 作用:SpringMvc使用@ResponseBody将结果以json返回客户端,  有些实体类的某些字段可以不被包括在JSON中;

思考了这种情况可能适用的情形:有多方调用这个接口,需要针对不同业务场景返回不同形式的JSON,但是这种情况的话 只拷贝需要的属性 再返回也能达到目的,就当多学了一种注解、处理方式了;

一.作为 Jackson Api使用:

public class View {
    public static class UserPublic{}

    public static class UserPrivacy{}
}
public class User {
    @JsonView(View.UserPublic.class)
    public int id;

    @JsonView(View.UserPrivacy.class)
    public String name;
}

补充说明:每一个@JsonView标注在属性上,代表该属性在被序列化时候会被转化,视图名字为value指向的class;

public class User {
    @JsonView(View.UserPublic.class)
    int id;

    @JsonView(View.UserPrivacy.class)
    String name;

    public void setId(int id) {
        this.id = id;
    }

    public void setName(String name) {
        this.name = name;
    }
}

public static void main(String[] args) throws JsonProcessingException {
    User user = new User();
    user.setId(1);
    user.setName("lvbb");
    ObjectMapper mapper = new ObjectMapper();
    String res1 = mapper.writerWithView(View.UserPublic.class).writeValueAsString(user);
    System.out.println(res1);
    String res2 = mapper.writerWithView(View.UserPrivacy.class).writeValueAsString(user);
    System.out.println(res2);
}

输出结果:

image_thumb2

 

@JsonView注解没有@Repeatable注解标注,意味着一个属性只能标注一个@JsonView注解,  比如 View.UserPrivacy 这个Json View也需要有id字段,解决方案就是 让 UserPrivacy 继承 UserPublic视图

image_thumb4

同样的main方法查看输出: {"id":1,"name":"lvbb"} 

 

二. 结合Spring的使用方式. (注解@JsonView的 value只能为一个)

简单列举个例子如下: 在@ResponseBody标注下添加  @JsonView指定要展示的JSON View即可.

    @RequestMapping("/demo2")
    @ResponseBody
    @JsonView(value = MyView.UserDetail.class)
    public User demo2(){
        User user = new User();
        user.setName("lvbinbin");
        user.setPassword("qwer0-5");
        return user;
    }

上面的代码使用效果和下面一段是一模一样的:

@RequestMapping(value = "/demo4")
    @ResponseBody
    public MappingJacksonValue demo4(){
        User user = new User();
        user.setName("lvbinbin");
        user.setPassword("qwer0-5");
        MappingJacksonValue mjv=new MappingJacksonValue(user);
        mjv.setSerializationView(MyView.UserDetail.class);
        return mjv;
    }

Json View  Api使用:

        User user = new User();
        user.setId(1);
        user.setName("lvbb");
        ObjectMapper mapper = new ObjectMapper();
        MappingJacksonValue mappingJacksonValue = new MappingJacksonValue(user);
        mappingJacksonValue.setSerializationView(View.UserPrivacy.class); 
        ObjectWriter writer = mapper.writerWithView(mappingJacksonValue.getSerializationView());
        String res4= writer.writeValueAsString(mappingJacksonValue.getValue());
        System.out.println(res4);

 

当然MappingJacksonValue好像也是支持SpringMvc跨域JSONP调用的,具体不太了解以后补上.

 

同样类似的,接收JSON请求参数使用 @RequestBody同样可以和 @JsonView使用,这时候前台接收到参数就可以忽略指定的字段

    @RequestMapping("/demo5")
    @ResponseBody
    public String demo5(@RequestBody @JsonView(MyView.UserSimple.class) User user){
        System.out.println(user);
        return "Hello World";
    }

 

Spring底层对MappingJacksonValue以及 @JsonView 流程记录:

MappingJackson的处理过程如下

org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter#writeInternal 有这样一个代码片段:

@ResponseBody的返回值类型是MappingJacksonValue类型时,会做的多一步转换工作,取出mappingJackson的value值.

image_thumb6

 

org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor#writeWithMessageConverters

在往响应对象Response写回结果之前, 会调用ResponseBodyAdvice接口的beforeBodyWrite方法进行切面处理,当前对象为 RequestResponseBodyAdviceChain,其持有JsonViewResponseBodyAdvice 以及JsonViewRequestBodyAdvice, 前者就是处理@ResponseBody的;

image_thumb8

JsonViewResponseBodyAdvice 直接获取了 方法上的JsonView注解,然后调用Jackson View Api进行设置;也就是说上面提及到的两种方式是一模一样的.

image_thumb10

 

参考文档:

一个关于jackson使用很全面的外文网站https://www.baeldung.com/jackson

转载于:https://www.cnblogs.com/lvbinbin2yujie/p/10575146.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值