Jackson——序列化——属性,键映射关系

  通常情况下,对象的属性与JSON键的关系是一对一,键的顺序是根据属性的顺序,键的名称是与属性的名称保持一致的。

Jackson有很多注解可以修改以上三种关系。首先从属性名称与键名称开始。

1、名称

1.1     @JsonProperty

在属性上添加@JsonProperty注解,给value赋值可以修改对应的键名称,例如User对象存在name属性,示例如下:

// json字符串中name属性对应的部分为{"userName":""}
@JsonProperty("userName")
private String name;

1.2   @JsonGetter & @JsonSetter

当属性不存在,只有get和set方法时,可以在set方法上添加@JsonSetter,get方法上添加@JsonGetter。

@JsonGetter("userName")
public String getName() {
    return name;
}

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

  二者的值可以不同,get对应的是序列化过程,set对应的反序列化过程

1.3   @JsonAlias

在属性上添加@JsonAlias注解,它的value为一个字符串数组,此时键名称可以是多个,在反序列化过程中,都可以映射为属性。

2、顺序

在类上添加@JsonPropertyOrder注解,可以自定义顺序,也可以按照属性名称字母排序。

@JsonPropertyOrder({"stringValue","intValue","listValue","dateValue"})
public class User{}
// 按照属性字母排序
@JsonPropertyOrder(alphabetic = true)
public class User {}

3、关系

属性与键值的映射关系有两种1对1, 1对0。

不存在一个属性生成多个键值的情形。

1对1为默认的关系。

1对0的情况,即在序列化过程中忽略该属性。实现方式有以下几种:

3.1     @JsonIgnore

在属性上添加@JsonIgnore注解,忽略该属性

@JsonIgnore
private String name;

3.2     @JsonIgnoreProperties

  在类上添加@JsonIgnoreProperties注解,批量忽略属性

// 忽略User对象中的name和age属性
@JsonIgnoreProperties({"name","age"})
public class User {}

3.3     @JsonIgnoreType

在该属性的类型上添加@JsonIgnoreType注解,例如User存在Address类型的属性

// User对象无需修改
@JsonIgnoreType
public class Address {}

3.4     @JsonAutoDetect

默认情况下,序列化时,只检测public修饰符的属性,若没有,会继续查找public修饰的get和set方法。

在类上添加@JsonAutoDect注解,给fieldVisibility赋值可以修改这种情况。它的值有以下几种类型,default对应默认情况

default:默认的规则

any包含所有的属性

none:不包含任何属性

non_private包含除private修饰的属性。

protected_and_public:包含protected和public修饰的属性

public_only仅包含public修饰的属性。

// 不包含private属性
@JsonAutoDetect(fieldVisibility= JsonAutoDetect.Visibility.NON_PRIVATE)
public class User{}

3.5     @JsonInclude

在类上,或属性上,或get或set方法上添加@JsonInclude注解,它是根据属性值进行判断是否包含属性,它的value值有以下六种类型

JsonInclude.Include.Always包含所有的属性,它是默认值。

JsonInclude.Include.NON_NULL不包含值为null的属性,当属性为集合类型时,为List时,不包含null值。为Map时,不包含key为null或value为null的键值对。

JsonInclude.Include.NON_ABSENT不包含引用为null的属性,即属性不是基本数据类型,它的引用指向null。同时包含NON_NULL情形。

JsonInclude.Include.NON_EMPTY不包含值为空的属性,属性值为空有以下五种场景NON_NULL; NON_ABSENT; 集合的isEmpty方法返回true; 数组的length为0;字符串的长度为0。

JsonInclude.Include.NON_DEFAULT不包含值为默认值,或为空的属性。例如int类型的属性值为0,布尔类型的属性值为false。

JsonInclude.Include.CUSTOM,使用时配置过滤器,过滤器方法返回false时,不包含该属性。

JsonInclude.Include.USE_DEFAULT,默认情形,通常用于覆盖作用域更广的值。例如类上存在NON_NULL, 在属性上指定USE_DEFAULT。

// 集合类型时使用contentFilter
@JsonInclude(value = JsonInclude.Include.CUSTOM, 
valueFilter = UserNameFilter.class)
private String name;

// 过滤器,重写equals方法,返回false时不包含
public class UserNameFilter {

    @Override
    public boolean equals(Object object){
        if (object == null || !(object instanceof String)) {
            return false;
        }
        String name = (String)object;
        return name.length() == name.trim().length();
    }
}

3.6     @JsonView

@JsonView相当于tag,根据tag为属性进行分组,例如创建必须的和可选的JsonView

public class JacksonView {
    // 可选的
    public interface OptionalView{}
    // 必然的
    public interface NecessaryView{}
}

  在属性上添加@JsonView注解

@JsonView(value = JacksonView.NecessaryView.class)
private String name;

  后续调用ObjectMapper的writerWithView方法

om.writerWithView(JacksonView.NecessaryView.class).writeValueAsString(customer);

3.7     @JsonFilter

@JsonFilter用于在序列化过程中添加过滤器,步骤如下。

第一步,在类上添加@JsonFilter注解,设置value属性,它为Filter的ID,假设值为”testFilter”

@JsonFilter("testFilter")
public class User {
}

  第二步,在序列化过程中创建SimpleFilterProvider对象,调用addFilter方法,第一个参数为Filter的ID, 第二个参数为PropertyFilter的子类。

SimpleFilterProvider filterProvider = new SimpleFilterProvider();
filterProvider.addFilter("testFilter",
      SimpleBeanPropertyFilter.filterOutAllExcept("name", "sex"));

  第三步,调用ObjectMapper对象的setFilterProvider方法。

om.setFilterProvider(filterProvider);

  具体参考SimpleBeanPropertyFilter对象。

posted @ 2021-03-22 10:41  蜗牛旅行1899  阅读(352)  评论(0编辑  收藏  举报