简介
Jackson是Java的一套数据处理工具,包括一流的JSON解析/生成库,匹配数据绑定库(用于类与JSON串之间的转换),和其他数据格式模块,以处理Avro、BSON、CBOR、CSV、Smile、(Java) Properties、Protobuf、XML或YAML编码的数据。
三个核心模块
- Streaming (jackson-core包):定义了低级流式API,包括了特定json的实现。
- Annotations (jackson-annotations包):包含标准的Jackson注解。
- Databind (jackson-databind包):实现了数据绑定,依赖于Streaming和Annotations。(导入jackson-databind包会自动导入其他两个包)
什么是序列化和反序列化
- 序列化(serialization):JSON对象 -> JSON字符串
- 反序列化(deserialization):JSON字符串 -> JSON对象
Jackson的序列化和反序列化
- Jackson默认序列化public的属性和getter方法,所以如果是public的属性可以不需要getter方法,但如果是private的属性,就需要有标准的getter方法。
- Jackson的反序列化public的属性和getter方法,所以如果是public的属性可以不需要setter方法,但如果是private的属性,就需要有标准的setter方法。Jackson反序列化时默认使用无参构造方法创建对象。
引入依赖
一般情况下
com.fasterxml.jackson.core
jackson-databind
2.11.1
引入jackson-databind会关联引入jackson-annotations和jackson-core。
SpringBoot下
spring-boot-starter-web包中自带了jackson的核心类库,所以不用再手动引入。
ObjectMapper使用
在Jackson中使用ObjectMapper对象来进行序列化和反序列化操作。
下面使用Car来作为操作演示的类:
public class Car {
private String color;
private String type;
// standard getters setters
}
序列化操作
ObjectMapper objectMapper = new ObjectMapper();
Car car = new Car("yellow", "renault");
objectMapper.writeValue(new File("target/car.json"), car);// 序列化到文件
String carAsString = objectMapper.writeValueAsString(car);// 序列化成String
反序列化操作
JSON 反序列化成 Java Object
String json = "{\"color\":\"yellow\",\"type\":\"renault\"}";
ObjectMapper mapper = new ObjectMapper();
Car car = mapper.readValue(json, Car.class);
JSON 反序列化成 Jackson的JsonNode类型
String json = "{\"color\":\"yellow\",\"type\":\"renault\"}";
ObjectMapper mapper = new ObjectMapper();
JsonNode jsonNode = mapper.readTree(json);
String type = jsonNode.get("type").asText();
JSNO数组 反序列化成 Java List类型
// 方式1(推荐)
String jsonCarArray = "[{ \"color\" : \"Black\", \"type\" : \"BMW\" }, { \"color\" : \"Red\", \"type\" : \"FIAT\" }]";
List listCar = objectMapper.readValue(jsonCarArray, new TypeReference>(){});
// 方式2
String jsonCarArray = "[{ \"color\" : \"Black\", \"type\" : \"BMW\" }, { \"color\" : \"Red\", \"type\" : \"FIAT\" }]";
objectMapper.configure(DeserializationFeature.USE_JAVA_ARRAY_FOR_JSON_ARRAY, true);
Car[] cars = objectMapper.readValue(jsonCarArray, Car[].class);
JSON 反序列化成 Map类型
String json = "{ \"color\" : \"Black\", \"type\" : {\"a\": 22}, \"arr\":[\"aa\", \"bb\"] }";
Map map = new ObjectMapper().readValue(json, new TypeReference
Jackson注解
下面按照功能划分了Jackson的注解,并给予了简要的文字解释。具体注解使用示例,可以参考文章Jackson Annotation Examples
Jackson的序列化注解
- @JsonAnyGetter:作用于Map字段的getter方法上,可以将该Map字段中的键值对作为类的标准属性来序列化。例如:@JsonAnyGetter
- @JsonGetter:以某个将方法标记为getter方法,是@JsonProperty的替代方法。例如:@JsonGetter("name")
- @JsonPropertyOrder:指定序列化时属性的顺序。例如:@JsonPropertyOrder({ "name", "id" })、@JsonPropertyOrder(alphabetic=true)
- @JsonRawValue:指定属性按照原生字符串的形式进行序列化,即不会对字符串进行转义,在需要嵌入Json字符串时很有用。例如:@JsonRawValue
- @JsonValue:指定使用某个方法来序列化整个实例。例如:@JsonValue
- @JsonRootName:当开启了SerializationFeature.WRAP_ROOT_VALUE时,用于指定包装实体的名称。例如:@JsonRootName(value = "user")
- @JsonSerialize:表示在序列化时使用指定的自定义序列化器。例如:@JsonSerialize(using = CustomDateSerializer.class)
Jackson的反序列化注解
- @JsonCreator:作用于类的构造方法或工厂方法上,表示用于反序列化生成对象,当JSON与实体不完全匹配时很有用。例如:@JsonCreator
- @JacksonInject:表示属性将从注入中获取其值,而不是从JSON数据中。例如:@JacksonInject
- @JsonAnySetter:表示反序列化时可以将未知属性用Map接收。例如:@JsonAnySetter
- @JsonSetter:将方法标记为setter方法,是@JsonProperty的一种替代方法。当JSON与属性值不匹配时很有用。例如:@JsonSetter("name")
- @JsonDeserialize:表示使用自定义反序列化器。例如:@JsonDeserialize(using = CustomDateDeserializer.class)
- @JsonAlias:在反序列化期间为属性定义一个或多个可选名称。例如:@JsonAlias({ "fName", "f_name" })
Jackson的属性包含注解
- @JsonIgnoreProperties:类级别注解,表示某些类的字段在序列化和反序列化时会被忽略。有个ignoreUnknown的配置,为true时会忽略反序列化时未知的属性,默认为false,即当有未知属性时会抛出异常。例如:@JsonIgnoreProperties(value = {"id"}, ignoreUnknown = true)
- @JsonIgnore:字段级别注解,表示该字段会被Jackson忽略。例如:@JsonIgnore
- @JsonIgnoreType:类级别注解,表示该类的所有字段都会被Jackson忽略。例如:@JsonIgnoreType
- @JsonInclude:在反序列化时,可用于排除带有空/空/默认值的属性。例如:@JsonInclude(value = JsonInclude.Include.NON_NULL)
- @JsonAutoDetect:可以改变默认的字段可见性。默认不可见private字段。例如:@JsonAutoDetect(fieldVisibility = Visibility.ANY)
- @JsonTypeInfo、@JsonSubTypes、@JsonTypeName:用于处理多态的注解。
Jackson的通用注解
- @JsonProperty:用来指定序列化和反序列化的属性名映射。例如:@JsonProperty("name")
- @JsonFormat:在序列化和反序列化Date/Time值时指定格式,默认的时区是格林威治时间。例如:@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
- @JsonUnwrapped:表示在序列化/反序列化时应该取消对象的包装。例如:@JsonUnwrapped
- @JsonView:可用于序列化/反序列化时字段的可见性问题。
- @JsonManagedReference, @JsonBackReference:可用于处理循环依赖问题。
- @JsonIdentityInfo:可用于处理循环依赖问题。
- @JsonFilter:在序列化时指定Filter。
- @JacksonAnnotationsInside:用于自定义注解。
Jackson Feature
常用的Jackson特性开关:
- DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES:反序列化时有未知属性则失败。默认是。
- SerializationFeature.WRAP_ROOT_VALUE:指定序列化时包装根对象。默认否。
- MapperFeature.USE_ANNOTATIONS:使用注解,默认是。
可以使用mapper的configure()、enable()、disable()来配置特性,例如:
ObjectMapper mapper = new ObjectMapper();
mapper.disable(SerializationFeature.WRAP_ROOT_VALUE);
mapper.disable(MapperFeature.USE_ANNOTATIONS);
@JsonFormat和@DateTimeFormat的区别
@JsonFormat
是Jackson的注解,在JSON进行序列化和反序列化Date/Time值时指定格式。由于Jackson默认的时区是格林威治时间,而我们是在东八区上,所以时间会比实际我们想得到的时间少八个小时,所以我们需要设置指定的时区:
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
在SpringBoot中,可以通过配置文件统一配置时间格式和时区
// 配置文件统一配置
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=GMT+8
@DateTimeFormat
是Spring的注解,用于将Get请求中URL路径中的参数格式化为Date类型。不能指定时区,默认就是当前时区
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")