简介

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反序列化时默认使用无参构造方法创建对象。

引入依赖

一般情况下

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

引入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<Car> listCar = objectMapper.readValue(jsonCarArray, new TypeReference<List<Car>>(){});

// 方式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<String, Object> map = new ObjectMapper().readValue(json, new TypeReference<Map<String, Object>>() {});
System.out.println("map = " + map);

String color = (String) map.get("color");
System.out.println("color = " + color);

Map type= (Map) map.get("type");
Integer a = (Integer) type.get("a");
System.out.println("a = " + a);

List arr = (List) map.get("arr");
System.out.println("arr = " + arr);

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")

参考资料


fsta
8 声望0 粉丝