导入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进行解析读取,也可以用于序列化、反序列化。