在上一篇中,我们学习了如何忽略值为null的字段《Jackson忽略null字段的3种方法》。
相对于忽略null字段,在实际应用中,忽略某些字段的序列化可能更为常见。
Jackson对于如何序列化字段、过滤字段的方法多种多样,非常丰富,这一节先来了解一下3种简单的方法。
本篇内容基于Jackson 2.11.2版本,马上开始学习吧。
使用JsonIgnore注解忽略单个字段
为字段添加@JsonIgnore注解,可以忽略该字段的序列化和反序列化。
public class ArticleIgnore {
private String title;
@JsonIgnore
private String summary;
private String content;
@JsonIgnore
private String author;
// 省略setter、getter方法
@Override
public String toString() {
return "ArticleIgnore [title=" + title + ", summary=" + summary + ", content=" + content + ", author=" + author
+ "]";
}
}
/**
* 为字段添加@JsonIgnore注解,可以忽略该字段的序列化和反序列化。
*
* @throws JsonProcessingException
*/
@Test
public void jsonIgnore() throws JsonProcessingException {
ArticleIgnore article = new ArticleIgnore();
article.setTitle("title");
article.setSummary("summary");
article.setContent("content");
article.setAuthor("author");
ObjectMapper mapper = new ObjectMapper();
System.out.println(mapper.writeValueAsString(article));
String str = "{\"title\":\"title\",\"summary\":\"summary\",\"content\":\"content\",\"author\":\"author\"}";
ArticleIgnore newArticle = mapper.readValue(str, ArticleIgnore.class);
System.out.println(newArticle.toString());
}
执行结果:
{"title":"title","content":"content"}
ArticleIgnore [title=title, summary=null, content=content, author=null]
使用JsonIgnoreProperties注解忽略多个字段
为类添加JsonIgnoreProperties注解,可以忽略指定多个字段的序列化和反序列化。
@JsonIgnoreProperties({ "summary", "author" })
public class ArticleIgnoreProperties {
private String title;
private String summary;
private String content;
private String author;
// 省略getter、setter方法
@Override
public String toString() {
return "ArticleIgnoreProperties [title=" + title + ", summary=" + summary + ", content=" + content + ", author="
+ author + "]";
}
}
/**
* 为类添加@JsonIgnoreProperties注解,忽略指定字段的序列化和反序列化。
*
* @throws JsonProcessingException
*/
@Test
public void jsonIgnoreProperties() throws JsonProcessingException {
ArticleIgnoreProperties article = new ArticleIgnoreProperties();
article.setTitle("title");
article.setSummary("summary");
article.setContent("content");
article.setAuthor("author");
ObjectMapper mapper = new ObjectMapper();
System.out.println(mapper.writeValueAsString(article));
String str = "{\"title\":\"title\",\"summary\":\"summary\",\"content\":\"content\",\"author\":\"author\"}";
ArticleIgnoreProperties newArticle = mapper.readValue(str, ArticleIgnoreProperties.class);
System.out.println(newArticle.toString());
}
执行结果:
{"title":"title","content":"content"}
ArticleIgnoreProperties [title=title, summary=null, content=content, author=null]
JsonIgnore作用于单个字段,JsonIgnoreProperties作用于类的多个字段,两者都是用来忽略指定的字段。
除此之外,还有另外一个以JsonIgnore开头的注解JsonIgnoreType,用于忽略指定类型(类、接口)的字段。
JsonIgnoreType注解
使用JsonIgnoreType注解忽略指定类型的字段
在指定的类型上,添加@JsonIgnoreType注解,可以忽略该类型的字段进行序列化。
public class AnimalIgnoreType {
private String name;
private Date date;
private Address address;
@JsonIgnoreType
public static class Address {
private String city;
// 忽略getter、setter方法
@Override
public String toString() {
return "Address [city=" + city + "]";
}
}
// 忽略getter、setter方法
@Override
public String toString() {
return "AnimalIgnoreType [name=" + name + ", date=" + date + ", address=" + address + "]";
}
}
/**
* 如果需要忽略某个具体的类型(类、接口)的序列化,可以使用@JsonIgnoreType注解来实现。
*
* @throws JsonProcessingException
*/
@Test
public void ignoreType() throws JsonProcessingException {
AnimalIgnoreType animal = new AnimalIgnoreType();
animal.setName("sam");
animal.setDate(new Date());
AnimalIgnoreType.Address address = new AnimalIgnoreType.Address();
address.setCity("gz");
animal.setAddress(address);
ObjectMapper mapper = new ObjectMapper();
System.out.println(mapper.writeValueAsString(animal));
String jsonString = "{\"name\":\"sam\",\"date\":1601714443779,\"address\":{\"city\":\"gz\"}}";
AnimalIgnoreType newAnimal = mapper.readValue(jsonString, AnimalIgnoreType.class);
System.out.println(newAnimal.toString());
}
执行结果:
{"name":"sam","date":1601726994454}
AnimalIgnoreType [name=sam, date=Sat Oct 03 16:40:43 CST 2020, address=null]
由于Address类型添加了忽略类型的注解,因此在序列化和反序列化时该类型的字段被忽略了。
使用JsonIgnoreType注解动态忽略指定类型的字段
前面使用JsonIgnoreType注解,忽略的类型是固定的。
利用ObjectMapper的addMixIn方法,可以动态的将JsonIgnoreType注解应用于其他数据类型。
public class AnimalIgnoreType {
private String name;
private Date date;
private Address address;
public static class Address {
private String city;
// 省略getter、setter方法
@Override
public String toString() {
return "Address [city=" + city + "]";
}
}
// 省略getter、setter方法
@Override
public String toString() {
return "AnimalIgnoreType [name=" + name + ", date=" + date + ", address=" + address + "]";
}
}
首先,定义一个空的类,并添加JsonIgnoreType注解。
@JsonIgnoreType
public class IgnoreType {}
在序列化时,调用ObjectMapper的addMixIn方法,将JsonIgnoreType注解应用于目标类。
下面的例子,会将IgnoreType类的注解,添加到Date和Address上,因此序列化时这两个类对应的字段会被忽略。
/**
* 调用ObjectMapper的addMixIn方法,将@JsonIgnoreType注解应用于任意目标类.
*
* @throws JsonProcessingException
*/
@Test
public void mixIn() throws JsonProcessingException {
AnimalIgnoreType animal = new AnimalIgnoreType();
animal.setName("sam");
animal.setDate(new Date());
AnimalIgnoreType.Address address = new AnimalIgnoreType.Address();
address.setCity("gz");
animal.setAddress(address);
ObjectMapper mapper = new ObjectMapper();
mapper.addMixIn(Date.class, IgnoreType.class);
mapper.addMixIn(Address.class, IgnoreType.class);
System.out.println(mapper.writeValueAsString(animal));
}
执行结果:
{"name":"sam"}
小结
如果需要忽略某个指定的字段,使用JsonIgnore注解是最简单的方式。
如果需要忽略多个字段,有时候可能还会调整,那么使用JsonIgnoreProperties注解将会更加灵活。
有时候,要忽略的是指定数据类型的字段,上面两种方法就不太方便了。Jackson为我们提供了另外一种方式,可以使用JsonIgnoreType注解来忽略某个固定的类型,或者结合ObjectMapper的addMixIn方法来动态忽略某个数据类型的字段。
参考
https://www.baeldung.com/jackson-ignore-properties-on-serialization (opens in a new tab)