中篇|Jackson注解的用法和场景,建议收藏
前言
今天我们接着上一篇文章梳理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
枚举可以实现那些属性可以序列化,那些属性可以反序列化(类似忽略的效果)。
-
@Data
-
public class MapUser {
-
@JsonProperty(value = "myname")
-
private String name;
-
@JsonProperty(value = "a")
-
private Integer age;
-
}
-
-
// {"myname":"felord.cn","a":22,"}
小结
本篇接着上一篇梳理了一部分Jackson注解的用法和场景,希望能够帮助你日常的开发。还有一部分基于篇幅的原因会在下一篇梳理完毕,还请多多关注和支持。
OpenJDK官方正式宣布AWT、2D、Swing等项目解散
文章来源: felord.blog.csdn.net,作者:码农小胖哥,版权归原作者所有,如需转载,请联系作者。
原文链接:felord.blog.csdn.net/article/details/118948541
- 点赞
- 收藏
- 关注作者
评论(0)