中篇|Jackson注解的用法和场景,建议收藏

举报
码农小胖哥 发表于 2022/03/31 23:45:44 2022/03/31
【摘要】 前言 今天我们接着上一篇文章梳理Jackson的注解。 Jackson注解一览 @JsonFormat 用于序列化和反序列化中特定格式的数据。虽然我们经常使用它来格式化时间,但是它不单单能格式化时间。 格式化时间 这种比较常用,主要用于格式化旧时间API: @Datapublic class&nbs...

前言

今天我们接着上一篇文章梳理Jackson的注解。

Jackson注解一览

@JsonFormat

用于序列化和反序列化中特定格式的数据。虽然我们经常使用它来格式化时间,但是它不单单能格式化时间。

格式化时间

这种比较常用,主要用于格式化旧时间API:


   
  1. @Data
  2. public class JsonFormatUser {
  3.     @JsonFormat(shape = JsonFormat.Shape.NUMBER)
  4.     private Date number;
  5.     @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
  6.     private Date yyyymmdd;
  7.     @JsonFormat(locale = "zh_CN")
  8.     private Date cnDate;
  9. }

三种shape分别输出时间戳,根据时区和既定格式格式化、本地化:


   
  1. {
  2.   "number" : 1626706386340,
  3.   "yyyymmdd" : "2021-07-19 22:53:06",
  4.   "cnDate" : "2021-07-19T14:53:06.340+00:00"
  5. }

说实话,现在都使用新的时间API,这个注解并不推荐使用。

注意:格式化时间需要带时区。

格式化枚举


   
  1. public enum GenderEnum {
  2.     /**
  3.      * Female gender.
  4.      */
  5.     FEMALE("0","女"),
  6.     /**
  7.      * Male gender.
  8.      */
  9.     MALE("1","男"),
  10.     /**
  11.      * Unknown gender.
  12.      */
  13.     @JsonEnumDefaultValue
  14.     UNKNOWN("-1","未知");
  15.     private final String value;
  16.     private final String description;
  17.     GenderEnum(String value, String description) {
  18.         this.value = value;
  19.         this.description = description;
  20.     }
  21.     public String getValue() {
  22.         return value;
  23.     }
  24.     public String getDescription() {
  25.         return description;
  26.     }
  27. }

上面这种枚举类只能格式化成枚举名称,很多时候我们期望能够获取键值对的枚举格式,例如GenderEnum.FEMALE:

{"value":"0","description":"女"}

  

我们只需要使用@JsonFormatshape特性:


   
  1. @JsonFormat(shape = JsonFormat.Shape.OBJECT)
  2. public enum GenderEnum {
  3. // 省略
  4. }

@JsonGetter和@JsonGetter

json序列化和反序列化时指定属性的Getter和Setter方法。特别针对有些不正规的方法,同时还可以指定别名,例子:


   
  1. public class GetterAndSetter {
  2.     private String name;
  3.     @JsonGetter("n")
  4.     public String name(){
  5.         return this.name;
  6.     }
  7.     @JsonSetter("name")
  8.     public void name(String name){
  9.         this.name= name;
  10.     }
  11. }

断言测试:


   
  1. GetterAndSetter getterAndSetter = new GetterAndSetter();
  2. getterAndSetter.name("felord.cn");
  3. String s = objectMapper.writeValueAsString(getterAndSetter);
  4. Object n = JsonPath.parse(s)
  5.         .read(JsonPath.compile("$.n"));
  6. Assertions.assertEquals("felord.cn",n);
  7. String json = "{\"name\":\"felord.cn\"}";
  8. GetterAndSetter getAndSet = objectMapper.readValue(json, GetterAndSetter.class);
  9. Assertions.assertEquals("felord.cn",getAndSet.name());

大部分情况下这两个注解比JsonProperty注解更加通用。

@JsonIdentityInfo

这个作用于类或属性上,被用来在序列化/反序列化时为该对象或字段添加一个对象识别码,比如@id或者Class对象名,主要解决字段循环嵌套的问题,例如数据库中的多对多关系,Bean嵌套依赖。开发ORM的相关功能时会用到。目前胖哥还没遇到这种场景。

扩展@JsonIdentityReference 具有类似的功能,强调了使用id作为标识。

@JsonIgnore

这个也是常用的一个注解。在序列化/反序列化时忽略被该注解标记的属性。这个注解和前面介绍的@JsonFilter提供的功能差不多。不过该注解是静态标记。

注意JsonProperty注解的access也可以实现该注解的功能,不建议两个注解混用,这样可能发生冲突。

@JsonIgnoreProperties

这个也经常使用。在序列化/反序列化时忽略多个属性,标记在类上。例如忽略internalIdsecretKey属性:

@JsonIgnoreProperties({ "internalId""secretKey" }

  

干脆点,如果有些属性我们不太确定我们也可以通过该注解过滤掉,避免未知属性异常:

@JsonIgnoreProperties(ignoreUnknown=true)

  

@JsonIgnoreType

序列化/反序列化时如果我们希望忽略掉某种特定类型可以借助于该注解:


   
  1.      @JsonIgnoreType
  2.     class Credentials {
  3.        public String password;
  4.     }
  5.   
  6.     class Settings {
  7.        public int userId;
  8.        public String name;
  9.        public Credentials pwd;
  10.     }

Settings进行序列化和反序列化时Credentials将会被忽略掉。主要用来对一些数据敏感的对象进行忽略,比如用户的凭据。

@JsonInclude

用于指示属性何时可以被序列化,我们可以把该注解标记到属性字段上,也可以通过setSerializationInclusion 方法统一设置。常用的JsonInclude.Include.NON_NULL可以过滤空值:


   
  1. Player player = new Player();
  2. player.setId(1);
  3. player.setName(null);

对应:


   
  1. {
  2. "id":1
  3. }

其它策略参见JsonInclude.Include

扩展:使用CUSTOM策略时可以实现自定义测过滤方法。

@JsonIncludeProperties

这个注解机制有点类似@JsonIgnoreProperties,只不过它的功能和@JsonIgnoreProperties相反。如果一个类标记了这个注解:

@JsonIncludeProperties({ "internalId""secretKey" })

  

除了internalIdsecretKey属性,其它属性都不参与序列化和反序列化。

@JsonProperty

@JsonProperty也是常用注解。用来标记属性或者属性的getter和setter方法上,用于指定属性的json名称,类似@JsonAlias的效果,同时配合其Access枚举可以实现那些属性可以序列化,那些属性可以反序列化(类似忽略的效果)。


   
  1. @Data
  2. public class MapUser {
  3.     @JsonProperty(value = "myname")
  4.     private String name;
  5.     @JsonProperty(value = "a")
  6.     private Integer age;
  7. }
  8. // {"myname":"felord.cn","a":22,"}

小结

本篇接着上一篇梳理了一部分Jackson注解的用法和场景,希望能够帮助你日常的开发。还有一部分基于篇幅的原因会在下一篇梳理完毕,还请多多关注和支持。

上篇|Jackson注解的用法和场景,不看巨亏

2021-07-15

OpenJDK官方正式宣布AWT、2D、Swing等项目解散

2021-07-17

文章来源: felord.blog.csdn.net,作者:码农小胖哥,版权归原作者所有,如需转载,请联系作者。

原文链接:felord.blog.csdn.net/article/details/118948541

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。