【Java】Jackson

/ 0评 / 0

导入Jackson依赖

主要有三个依赖:jackson-core、jackson-annotations和jackson-databind,其中jackson-databind依赖其它两个,因此引入jackson-databind就可以传递引入这三个依赖,Jackson的最新稳定版本为2.17.0:

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.17.0</version>
</dependency>

Jackson原理

Java中进行序列化和反序列化的主要手段是反射,Jackson主要通过反射来访问对象的字段或者执行对象的方法:一般情况下Jackson优先使用Getter/Setter方法来读取和修改对象的字段,如果对象中没有关于该字段的Getter/Setter方法,Jackson将通过反射直接访问和修改字段的值。由于使用反射,因此字段及其Getter/Setter方法的访问级别是无关紧要的,即便是private级别也不影响序列化和反序列化的进行。

在反序列化时Jackson首先需要创建对象实例,默认情况下Jackson使用无参数的构造函数来实现对象的创建,使用Jackson的相关注解可以指定其它构造函数。

对于泛型类型,由于Java的泛型擦除特点,反序列化时并不能直接获取到对象的类型信息,Jackson使用TypeReference来解决这个问题。

public abstract class TypeReference<T> implements Comparable<TypeReference<T>> {
    protected final Type _type;

    protected TypeReference() {
        Type superClass = this.getClass().getGenericSuperclass();
        if (superClass instanceof Class) {
            throw new IllegalArgumentException("Internal error: TypeReference constructed without actual type information");
        } else {
            this._type = ((ParameterizedType)superClass).getActualTypeArguments()[0];
        }
    }

    public Type getType() {
        return this._type;
    }

    public int compareTo(TypeReference<T> o) {
        return 0;
    }
}

TypeReference<T>是泛型抽象类型,在其构造函数里它通过反射来记录类型T的信息。由于是抽象类,因此为了创建TypeReference对象,必须使用Java的匿名类语法 { }

TypeReference<List<String>> ref = new TypeReference<List<String>>() {};

Jackson注解

在无注解的情况下,Jackson会自动映射字段并优先考虑Getter/Setter方法,如getName方法将自动映射到JSON中的name字段,如果不存在Getter/Setter方法那么将从字段名进行推断,即映射到JSON中的同名字段。为了改变上述默认行为,可以使用Jackson提供的各类注解。

@JsonProperty:可修饰字段、方法或参数,显式映射JSON字段,可以通过value属性指定JSON字段名,该注解可以提高可读性,也可用于映射到不同名的JSON字段。

[S] @JsonAnyGetter:用于修饰字段或方法,字段或方法返回值的类型为一个Map,其中的内容将被序列化为JSON字段。

[S] @JsonGetter:用于修饰方法,可替代@JsonProperty,显式指定该方法为Getter方法,可以通过value属性指定JSON字段名。

[S] @JsonPropertyOrder:用于修饰类,指定序列化时字段的顺序,如下。使用其alphabetic属性可以指定字段按字典排序。

@JsonPropertyOrder({ "name", "value" })
public class ExtendableBean {
    public String name;
    public int value;

    @JsonGetter
    public String getName() {
        return name;
    }
    
    @JsonGetter
    public int getValue(){
        return value;
    }
}

[S] @JsonRawValue:用于修饰字段或方法,指定Jackson按原样保存为JSON字段,主要用于将字段保存的预序列化的JSON文本在当前对象序列化时嵌入。

[S] @JsonValue:用于修饰字段或方法,指定Jackson将此字段值或者方法的返回值序列化,并作为当前整个对象的序列化结果。

[S] @JsonRootName:用于修饰类,将序列化后的JSON进行包装,value属性指定JSON中包装对象的名称。

[D] @JsonCreator:用于修饰构造器方法或者静态方法,指定Jackson反序列化时应该使用的方法,默认情况下Jackson使用对象的无参数构造函数,使用该注解可以改变这一行为。通常注解于一个带参数的构造函数,以便反序列化那些与当前类型不完全匹配的JSON,由于Java反射并不能在运行时获取到参数名称,因此一般配合使用@JsonProperty注解方法参数。如:

public class ExtendableBean {
    public String name;
    public int value;

    public ExtendableBean() {}

    @JsonCreator
    public ExtendableBean(@JsonProperty("_name") String name, @JsonProperty("_value") int value) {
        this.name = name;
        this.value =value;
    }
}

[D] @JsonAnySetter:用于修饰字段或方法,字段类型为Map,或所修饰的方法接收两个参数分别代表字段名和字段值,在反序列化时无法识别(无法映射到任何对象字段或任何Setter方法)的JSON字段将传递到Map或方法参数中,如果存在无法识别的JSON字段,同时又不存在@JsonAnySetter注解,反序列化将抛出异常。

[D] @JsonSetter:用于修饰方法,可替代@JsonProperty,显式指定该方法为Setter方法,可以通过value属性指定JSON字段名。

[D] @JsonAlias:用于修饰字段或者方法,可指定JSON字段别名。

[SD] @JsonIgnoreProperties:用于修饰类,value属性是一个字符串数组,表示Jackson应当忽略的字段名,这将同时影响序列化和反序列化,ignoreUnknown属性默认为假,如果为真表示Jackson应当忽略JSON中的所有未知字段。

[SD] @JsonIgnore:用于修饰字段、Getter/Setter方法或构造器方法中的参数,表示Jackson应当忽略相关的字段,该注解直接生效于整个字段,仅仅注解Getter方法也会导致Jackson忽略Setter方法,除非使用@JsonProperty注解Setter方法。

[SD] @JsonIgnoreType:用于修饰类,表示Jackson应当忽略该类中的所有字段,通常用于注解类型中的嵌套类。

[SD] @JsonInclude:用于修饰类或字段,表示Jackson应当忽略具有NULL值、空值或默认值的字段。value属性指定接受策略:

public static enum Include {
    ALWAYS,
    NON_NULL,
    NON_ABSENT,
    NON_EMPTY,
    NON_DEFAULT,
    CUSTOM,
    USE_DEFAULTS;

    private Include() {
    }
}

[SD] @JsonIncludeProperties:用于修饰类,value属性是一个字符串数组,表示Jackson应当考虑在内的字段名,这将同时影响序列化和反序列化。

[SD] @JsonAutoDetect:用于修饰类,指定Jackson序列化或反序列化时的检测策略,策略由如下几个可见性组成:

getterVisibility:Getter方法的可见性,Jackson将考虑无参数、具有返回值且以get作为前缀的方法。

setterVisibility:Setter方法的可见性,Jackson将考虑具有单个参数且以set作为前缀的方法。

isGetterVisibility:布尔型Getter方法的可见性,Jackson将考虑无参数、具有Boolean返回值且以is作为前缀的方法。

creatorVisibility:构造方法的可见性,Jackson将考虑构造函数及某些静态方法(如valueOf方法)。

fieldVisibility:字段的可见性。

可见性可以指定如下值(定义于JsonAutoDetect.Visibility):

ANY:无论其可见性如何,都将被Jackson检测。

NON_PRIVATE:只要可见性不是private,都将被Jackson检测。

PROTECTED_AND_PUBLIC:可见性是protected或者public。

PUBLIC_ONLY:可见性只能为public。

NONE:从不自动检测。

DEFAULT:采用默认值。

ObjectMapper

ObjectMapper是Jackson最常用的一个工具类,支持对JSON进行解析读取,也可以用于序列化、反序列化。

 

 

 

 

 

 

 

 

 

 

Leave a Reply

Your email address will not be published. Required fields are marked *