GitHub:https://github.com/FasterXML/jackson-annotations
1、属性命名(Property Naming)
@JsonProperty:用于指明属性的名称。
import java.util.Date;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@ToString
@JsonIgnoreProperties(ignoreUnknown=true)
public class Article {
private Long id;
private String title;
private String description;
private List<Author> authors;
//createDate->create_date
@JsonProperty("create_date")
private Date createDate;
}
测试:
@Test
public void jsonPropertyTest() throws IOException {
List<Author> authors = Lists.newArrayList(
Author.builder().name("zyc").fields(Lists.newArrayList("java", "sql")).build(),
Author.builder().name("llp").fields(Lists.newArrayList("cad", "excel")).build());
Article article = Article.builder().authors(authors).createDate(new Date()).description("use @JsonProperty change the property name.").id(168L)
.title("testJsonProperty").build();
ObjectMapper objMapper = new ObjectMapper();
//序列化
String jsonStr = objMapper.writeValueAsString(article);
System.out.println("序列化结果:" + jsonStr);
//反序列化
Article atl = objMapper.readValue(jsonStr, Article.class);
System.out.println("反序列化结果:" + atl);
}
序列化结果:{"id":168,"title":"testJsonProperty","description":"use @JsonProperty change the property name.","authors":[{"name":"zyc","fields":["java","sql"]},{"name":"llp","fields":["cad","excel"]}],"create_date":1521046139016}
反序列化结果:Article(id=168, title=testJsonProperty, description=use @JsonProperty change the property name., authors=[Author(name=zyc, fields=[java, sql]), Author(name=llp, fields=[cad, excel])], createDate=Thu Mar 15 00:48:59 CST 2018)
2、属性包含(Property Inclusion)
@JsonAutoDetect:用于指定自动发现字段的级别。
fieldVisibility:字段属性的可见范围。
getterVisibility:getter的可见范围(对象序列化成json字符串时的可见范围)。
isGetterVisibility:is-getter的可见范围(如boolean类型的getter)。
setterVisibility:setter的可见范围(json字符串反序列化成对象时的可见范围)。
creatorVisibility:构造方法的可见范围。
可见范围是一个枚举,包括:
Visibility.ANY:表示从private到public修饰,都可见。
Visibility.NON_PRIVATE:表示除private修饰不可见外,其他都可见。
Visibility.PROTECTED_AND_PUBLIC:protected和public可见。
Visibility.PUBLIC_ONLY:仅public可见。
Visibility.NONE:所以皆不可见。
Visibility.DEFAULT:缺省,所有被public修饰的属性、getter和所有setter(不管能见度)皆可见。
测试属性可见性:
先试ANY,protected修饰可见
@JsonIgnoreProperties(ignoreUnknown=true)
@JsonAutoDetect(fieldVisibility=Visibility.ANY)
public class Person {
protected String name = "zyc";
public boolean boy = true;
@Override
public String toString() {
return "Person [name=" + name + ", boy=" + boy + "]";
}
}
@Test
public void JsonAutoDetectTest() throws IOException {
Person person = new Person();
ObjectMapper objMapper = new ObjectMapper();
// 序列化
String jsonStr = objMapper.writeValueAsString(person);
System.out.println("序列化结果:" + jsonStr);
// 反序列化
Person p = objMapper.readValue("{\"name\":\"llp\", \"boy\":true}", Person.class);
System.out.println("反序列化结果:" + p);
}
序列化结果:{"name":"zyc","boy":true}
反序列化结果:Person [name=llp, boy=true]
再试PUBLIC_ONLY,protected不可见
@JsonIgnoreProperties(ignoreUnknown=true)
@JsonAutoDetect(fieldVisibility=Visibility.PUBLIC_ONLY)
public class Person {
protected String name = "zyc";
public boolean boy = true;
@Override
public String toString() {
return "Person [name=" + name + ", boy=" + boy + "]";
}
}
序列化结果:{"boy":true}
反序列化结果:Person [name=zyc, boy=true]
测试getter、setter可见性
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
@JsonIgnoreProperties(ignoreUnknown=true)
@JsonAutoDetect(getterVisibility=Visibility.NON_PRIVATE)
public class Person {
private String name = "zyc";
private boolean boy = true;
//getterVisibility=Visibility.NON_PRIVATE: protected 修饰的name可见
protected String getName() {
return name;
}
//setter默认所有可见,所以反序列化都会被赋值
private void setName(String name) {
this.name = name;
}
//isGetterVisibility默认为public修饰可见,所有序列化时,没有boy属性
private boolean isBoy() {
return boy;
}
private void setBoy(boolean boy) {
this.boy = boy;
}
@Override
public String toString() {
return "Person [name=" + name + ", boy=" + boy + "]";
}
}
序列化结果:{"name":"zyc"}
反序列化结果:Person [name=llp, boy=true]
@JsonIgnore:用于忽略指定属性,当该注解出现在field、getter、setter或者构造方法中任意一个上时,都意味着忽略所有(即序列化和反序列化都被忽略);有一种情况,当getter上注解@JsonIgnore而setter上注解@JsonProperty,就会出现“只读”情况(read from input, but is not written output)。
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
public class House {
private String name;
//仅仅注解 @JsonIgnore时,序列化和反序列化都忽略
@JsonIgnore
// @JsonProperty
private String address;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "House [name=" + name + ", address=" + address + "]";
}
}
@Test
public void JsonIgnoreTest() throws Exception {
House house = new House();
house.setName("my house");
house.setAddress("深圳");
ObjectMapper objMapper = new ObjectMapper();
// address被忽略
String jsonStr = objMapper.writeValueAsString(house);
System.out.println("序列化结果:" + jsonStr);
// address被忽略
House h = objMapper.readValue("{\"name\":\"your house\", \"address\":\"深圳南山\"}", House.class);
System.out.println("反序列化结果:" + h);
}
序列化结果:{"name":"my house"}
反序列化结果:House [name=your house, address=null]
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
public class House {
private String name;
//仅仅注解 @JsonIgnore时,序列化和反序列化都忽略
@JsonIgnore
//在属性上添加 @JsonProperty,结果是忽略不生效
@JsonProperty
private String address;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "House [name=" + name + ", address=" + address + "]";
}
}
序列化结果:{"name":"my house","address":"深圳"}
反序列化结果:House [name=your house, address=深圳南山]
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
public class House {
private String name;
//仅仅注解 @JsonIgnore时,序列化和反序列化都忽略
@JsonIgnore
private String address;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
//setter注解@JsonProperty,忽略被取消,和注解在属性上一样结果
@JsonProperty
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "House [name=" + name + ", address=" + address + "]";
}
}
序列化结果:{"name":"my house","address":"深圳"}
反序列化结果:House [name=your house, address=深圳南山]
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
public class House {
private String name;
private String address;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//getter注解 @JsonIgnore
@JsonIgnore
public String getAddress() {
return address;
}
//setter注解@JsonProperty,出现“只读”情况
@JsonProperty
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "House [name=" + name + ", address=" + address + "]";
}
}
序列化结果:{"name":"my house"}
反序列化结果:House [name=your house, address=深圳南山]
结论:当仅出现@JsonIgnore时,属性序列化和反序列化都被忽略;当@JsonIgnore和@JsonProperty同时出现,并且不是getter注解@JsonIgnore,setter注解@JsonProperty时,属性忽略被取消,正常序列化反序列化;当getter注解@JsonIgnore,setter注解@JsonProperty时,出现“只读”(getter注解@JsonProperty,setter注解@JsonIgnore是不存在只写的情况的^_^)。
@JsonIgnoreProperties:作用于实体类的注解(注解在属性貌似没效果),用于忽略某些属性,如果指定ignoreUnknown=true,则反序列化时忽略所有未知的属性;allowGetters使得被忽略的属性在序列化时是可见的,即序列化时忽略失效了;allowSetters对应反序列化。
@JsonIgnoreProperties(value={"cpu", "mainboard"}, allowGetters=true)
public class Computer {
private String cpu;
private String memory;
private String os;
public String getCpu() {
return cpu;
}
public void setCpu(String cpu) {
this.cpu = cpu;
}
public String getMemory() {
return memory;
}
public void setMemory(String memory) {
this.memory = memory;
}
public String getOs() {
return os;
}
public void setOs(String os) {
this.os = os;
}
@Override
public String toString() {
return "Computer [cpu=" + cpu + ", memory=" + memory + ", os=" + os + "]";
}
@Test
public void JsonIgnorePropertiesTest() throws Exception {
Computer cpt = new Computer();
cpt.setCpu("i7-U6700HQ");
cpt.setMemory("16G");
cpt.setOs("windows 10");
// 序列化
ObjectMapper objMapper = new ObjectMapper();
String jsonStr = objMapper.writeValueAsString(cpt);
System.out.println("序列化结果:" + jsonStr);
// 注意这里,如果忽略的属性数组里不包含mainboard,则会抛出com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException异常
Computer computer = objMapper.readValue(
"{\"cpu\":\"爱妻六代\", \"os\":\"centos7\",\"memory\":\"8G\",\"mainboard\":\"华硕主板\"}", Computer.class);
System.out.println("反序列化结果:" + computer);
}
序列化结果:{"cpu":"i7-U6700HQ","memory":"16G","os":"windows 10"}
反序列化结果:Computer [cpu=null, memory=8G, os=centos7]
@JsonIgnoreType:作用于类,表示被注解该类型的属性(这里不是指被注解类的成员变量,而是被注解类作为别的类的成员变量)将不会被序列化和反序列化。@JsonIgnoreType(value=false)表示该注解不起作用,默认为true。
public class Car {
private String name;
private double price;
private Owner owner;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public Owner getOwner() {
return owner;
}
public void setOwner(Owner owner) {
this.owner = owner;
}
}
import com.fasterxml.jackson.annotation.JsonIgnoreType;
@JsonIgnoreType
public class Owner {
private String name;
public Owner() {
}
public Owner(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Owner [name=" + name + "]";
}
}
@Test
public void JsonIgnoreTypeTest() throws JsonProcessingException {
Car car = new Car();
car.setName("迈腾");
car.setPrice(23.49);
car.setOwner(new Owner("zyc"));
ObjectMapper objMapper = new ObjectMapper();
String jsonStr = objMapper.writeValueAsString(car);
System.out.println("结果:" + jsonStr);
}
结果:{"name":"迈腾","price":23.49}
@JsonInclude:用于定义序列化时是否包括某些“non-values”(空值或空值);可作用于属性,也可以用于类(对类的所有属性有效)。
Include.ALWAYS
表示无论对象的属性是不是空,都输出到json字符串中Include.NON_NULL
表示序列化生成的json字符串仅包括非null的字段属性,为null的属性被忽略Include.NON_ABSENT
相当于NON_NULL的增强版,比如jdk和谷歌Guava的Optional类型对象,不是null,但它的isPresent方法返回falseInclude.NON_EMPTY
表示非空:指非null,非"",集合isEmpty()==true等都将被忽略Include.NON_DEFAULT
表示属性值为缺省值时不序列化,如int类型属性==0,String类型属性==null等Include.CUSTOM
这个要结合注解JsonInclude.valueFilter
和JsonInclude.contentFilter
使用,这两个注解会指定一个Class,然后默认调用这个Class的空参构造方法,返回的对象eques属性值的话,序列化时就忽略。如使用注解:@JsonInclude(valueFilter=String.class),然后javabean中String name="";则这个name在序列化为json时将被忽略,因为"".equals(new String())Include.USE_DEFAULTS
理解不了:Pseudo-value used to indicate that the higher-level defaults make sense, to avoid overriding inclusion value. For example, if returned for a property this would use defaults for the class that contains property, if any defined; and if none defined for that, then global serialization inclusion details.