SpringMvc @JsonView 使用方式

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

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

一.作为 Jackson Api使用:

1public class View { 2 public static class UserPublic{} 3 4 public static class UserPrivacy{} 5} 6 7public class User { 8 @JsonView(View.UserPublic.class) 9 public int id; 10 11 @JsonView(View.UserPrivacy.class) 12 public String name; 13}

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

1public class User { 2 @JsonView(View.UserPublic.class) 3 int id; 4 5 @JsonView(View.UserPrivacy.class) 6 String name; 7 8 public void setId(int id) { 9 this.id = id; 10 } 11 12 public void setName(String name) { 13 this.name = name; 14 } 15} 16 17public static void main(String[] args) throws JsonProcessingException { 18 User user = new User(); 19 user.setId(1); 20 user.setName("lvbb"); 21 ObjectMapper mapper = new ObjectMapper(); 22 String res1 = mapper.writerWithView(View.UserPublic.class).writeValueAsString(user); 23 System.out.println(res1); 24 String res2 = mapper.writerWithView(View.UserPrivacy.class).writeValueAsString(user); 25 System.out.println(res2); 26}

输出结果:

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即可.

1@RequestMapping("/demo2") 2 @ResponseBody 3 @JsonView(value = MyView.UserDetail.class) 4 public User demo2(){ 5 User user = new User(); 6 user.setName("lvbinbin"); 7 user.setPassword("qwer0-5"); 8 return user; 9 }

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

1@RequestMapping(value = "/demo4") 2 @ResponseBody 3 public MappingJacksonValue demo4(){ 4 User user = new User(); 5 user.setName("lvbinbin"); 6 user.setPassword("qwer0-5"); 7 MappingJacksonValue mjv=new MappingJacksonValue(user); 8 mjv.setSerializationView(MyView.UserDetail.class); 9 return mjv; 10 }

Json View  Api使用:

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

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

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

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

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

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

java将前端的json数组字符串转换为列表

记录下在前端通过ajax提交了一个json数组的字符串,在后端如何转换为列表。前端数据转化与请求varcontracts{id:'1',name:'yanggb合同1'},{id:'2',name:'yanggb合同2'},{id:'3',name:'yang

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )