前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >中篇|Jackson注解的用法和场景,建议收藏

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

作者头像
码农小胖哥
发布2021-07-22 15:59:17
1.5K0
发布2021-07-22 15:59:17
举报

前言

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

Jackson注解一览

@JsonFormat

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

格式化时间

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

代码语言:javascript
复制
@Data
public class JsonFormatUser {

    @JsonFormat(shape = JsonFormat.Shape.NUMBER)
    private Date number;
    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
    private Date yyyymmdd;
    @JsonFormat(locale = "zh_CN")
    private Date cnDate;

}

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

代码语言:javascript
复制
{
  "number" : 1626706386340,
  "yyyymmdd" : "2021-07-19 22:53:06",
  "cnDate" : "2021-07-19T14:53:06.340+00:00"
}

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

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

格式化枚举
代码语言:javascript
复制
public enum GenderEnum {

    /**
     * Female gender.
     */
    FEMALE("0","女"),
    /**
     * Male gender.
     */
    MALE("1","男"),
    /**
     * Unknown gender.
     */
    @JsonEnumDefaultValue
    UNKNOWN("-1","未知");

    private final String value;
    private final String description;

    GenderEnum(String value, String description) {
        this.value = value;
        this.description = description;
    }

    public String getValue() {
        return value;
    }

    public String getDescription() {
        return description;
    }

}

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

代码语言:javascript
复制
{"value":"0","description":"女"}

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

代码语言:javascript
复制
@JsonFormat(shape = JsonFormat.Shape.OBJECT)
public enum GenderEnum {
// 省略
}

@JsonGetter和@JsonGetter

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

代码语言:javascript
复制
public class GetterAndSetter {
    private String name;

    @JsonGetter("n")
    public String name(){
        return this.name;
    }

    @JsonSetter("name")
    public void name(String name){
        this.name= name;
    }
}

断言测试:

代码语言:javascript
复制
GetterAndSetter getterAndSetter = new GetterAndSetter();
getterAndSetter.name("felord.cn");

String s = objectMapper.writeValueAsString(getterAndSetter);
Object n = JsonPath.parse(s)
        .read(JsonPath.compile("$.n"));
Assertions.assertEquals("felord.cn",n);

String json = "{\"name\":\"felord.cn\"}";

GetterAndSetter getAndSet = objectMapper.readValue(json, GetterAndSetter.class);

Assertions.assertEquals("felord.cn",getAndSet.name());

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

@JsonIdentityInfo

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

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

@JsonIgnore

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

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

@JsonIgnoreProperties

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

代码语言:javascript
复制
@JsonIgnoreProperties({ "internalId", "secretKey" }

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

代码语言:javascript
复制
@JsonIgnoreProperties(ignoreUnknown=true)

@JsonIgnoreType

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

代码语言:javascript
复制
     @JsonIgnoreType
    class Credentials {
       public String password;
    }
  
    class Settings {
       public int userId;
       public String name;
       public Credentials pwd;
    }

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

@JsonInclude

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

代码语言:javascript
复制
Player player = new Player();
player.setId(1);
player.setName(null);

对应:

代码语言:javascript
复制
{
"id":1
}

其它策略参见JsonInclude.Include

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

@JsonIncludeProperties

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

代码语言:javascript
复制
@JsonIncludeProperties({ "internalId", "secretKey" })

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

@JsonProperty

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

代码语言:javascript
复制
@Data
public class MapUser {
    @JsonProperty(value = "myname")
    private String name;
    @JsonProperty(value = "a")
    private Integer age;
}

// {"myname":"felord.cn","a":22,"}

小结

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

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-07-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码农小胖哥 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • Jackson注解一览
    • @JsonFormat
      • 格式化时间
      • 格式化枚举
    • @JsonGetter和@JsonGetter
      • @JsonIdentityInfo
        • @JsonIgnore
          • @JsonIgnoreProperties
            • @JsonIgnoreType
              • @JsonInclude
                • @JsonIncludeProperties
                  • @JsonProperty
                  • 小结
                  相关产品与服务
                  文件存储
                  文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档