JSON类库Jackson注解一览(2)
前言
今天我们接着上一篇文章梳理Jackson的注解。
Jackson注解一览
@JsonFormat
用于序列化和反序列化中特定格式的数据。虽然我们经常使用它来格式化时间,但是它不单单能格式化时间。
格式化时间
这种比较常用,主要用于格式化旧时间API:
@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
分别输出时间戳,根据时区和既定格式格式化、本地化:
{
"number" : 1626706386340,
"yyyymmdd" : "2021-07-19 22:53:06",
"cnDate" : "2021-07-19T14:53:06.340+00:00"
}
说实话,现在都使用新的时间API,这个注解并不推荐使用。
注意:格式化时间需要带时区。
格式化枚举
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
:
{"value":"0","description":"女"}
我们只需要使用@JsonFormat
的shape
特性:
@JsonFormat(shape = JsonFormat.Shape.OBJECT)
public enum GenderEnum {
// 省略
}
@JsonGetter和@JsonGetter
json序列化和反序列化时指定属性的Getter和Setter方法。特别针对有些不正规的方法,同时还可以指定别名,例子:
public class GetterAndSetter {
private String name;
@JsonGetter("n")
public String name(){
return this.name;
}
@JsonSetter("name")
public void name(String name){
this.name= name;
}
}
断言测试:
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
这个也经常使用。在序列化/反序列化
时忽略多个属性,标记在类上。例如忽略internalId
和secretKey
属性:
@JsonIgnoreProperties({ "internalId", "secretKey" }
干脆点,如果有些属性我们不太确定我们也可以通过该注解过滤掉,避免未知属性异常:
@JsonIgnoreProperties(ignoreUnknown=true)
@JsonIgnoreType
在序列化/反序列化
时如果我们希望忽略掉某种特定类型可以借助于该注解:
@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
可以过滤空值:
Player player = new Player();player.setId(1);player.setName(null);
对应:
{"id":1}
其它策略参见JsonInclude.Include
。
扩展:使用
CUSTOM
策略时可以实现自定义测过滤方法。
@JsonIncludeProperties
这个注解机制有点类似@JsonIgnoreProperties
,只不过它的功能和@JsonIgnoreProperties
相反。如果一个类标记了这个注解:
@JsonIncludeProperties({ "internalId", "secretKey" })
除了internalId
和secretKey
属性,其它属性都不参与序列化和反序列化。
@JsonProperty
@JsonProperty
也是常用注解。用来标记属性或者属性的getter和setter方法上,用于指定属性的json名称,类似@JsonAlias
的效果,同时配合其Access
枚举可以实现那些属性可以序列化,那些属性可以反序列化(类似忽略的效果)。
@Datapublic class MapUser { @JsonProperty(value = "myname") private String name; @JsonProperty(value = "a") private Integer age;}// {"myname":"felord.cn","a":22,"}
小结
本篇接着上一篇梳理了一部分Jackson注解的用法和场景,希望能够帮助你日常的开发。还有一部分基于篇幅的原因会在下一篇梳理完毕,还请多多关注和支持。
评论系统未开启,无法评论!