• 公用技术——数据格式——JSON——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对象。

  • 相关阅读:
    JavaScript设计模式样例八 —— 适配器模式
    JavaScript设计模式样例七 —— 原型模式
    JavaScript设计模式样例六 —— 抽象工厂模式
    JavaScript设计模式样例五 —— 建造者模式
    JS比较两个时间的时间差
    使用nginx实现纯前端跨越
    npm的使用总结
    优雅的格式化时间显示
    优雅的封装ajax,含跨域
    将自己的域名代理到Gitpages
  • 原文地址:https://www.cnblogs.com/rain144576/p/14565072.html
Copyright © 2020-2023  润新知