详解Jackson 使用以及性能介绍

Jackson 是一个用于在Java对象和 json 数据之间进行转换的框架。它支持众多 json 数据格式,诸如 JSON-LD、SMILE 等。Jackson 是一个流式处理 JSON 的工具,它很容易与其它 JSON 处理工具进行集成,同时在序列化和反序列化性能方面也表现得相当优异。

详解Jackson 使用以及性能介绍

Jackson 简介

Jackson 是一个用于在Java对象和 json 数据之间进行转换的框架。它支持众多 json 数据格式,诸如 JSON-LDSMILE 等。Jackson 是一个流式处理 JSON 的工具,它很容易与其它 JSON 处理工具进行集成,同时在序列化和反序列化性能方面也表现得相当优异。

Jackson 基本使用

引入 Jackson

在项目中使用 Jackson 首先需要引入对 Jackson 的依赖。

如果你使用的是 Maven,你可以在项目的 pom.xml 文件里添加以下依赖:

<!-- Jackson -->
<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-core</artifactId>
  <version>2.12.5</version>
</dependency>

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

<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-annotations</artifactId>
  <version>2.12.5</version>
</dependency>

序列化

序列化是将 Java 对象转换成 json 数据的过程。使用 Jackson 进行序列化非常简单。

ObjectMapper objectMapper = new ObjectMapper();

Person person = new Person("Tony", "Stark", "Iron Man");
String json = objectMapper.writeValueAsString(person);
System.out.println(json);

以上代码中,我们首先创建了一个 ObjectMapper 对象,它是 Jackson 的核心类之一。然后创建了一个 Person 对象,并将其序列化成了一个 json 数据。

反序列化

反序列化是将 json 数据转换成 Java 对象的过程。同样的,使用 Jackson 进行反序列化也非常简单。

String json = "{\"firstName\":\"Tony\",\"lastName\":\"Stark\",\"alias\":\"Iron Man\"}";

ObjectMapper objectMapper = new ObjectMapper();

Person person = objectMapper.readValue(json, Person.class);
System.out.println(person);

以上代码中,我们首先创建了一个 Person 对象的 json 数据,然后创建了一个 ObjectMapper 对象,并使用 readValue 方法将其转换成了一个 Person 对象。

Jackson 性能介绍

Jackson 是一个性能优异的 JSON 处理框架。以下是一个对其性能表现的简单测试:

public class JacksonPerformanceTest { 
  private static ObjectMapper objectMapper = new ObjectMapper();

  @Test
  public void testPerformance() throws IOException {
    Person person = new Person("Tony", "Stark", "Iron Man");

    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    objectMapper.writeValue(baos, person);
    byte[] bytes = baos.toByteArray();

    long start = System.nanoTime();
    for (int i = 0; i < 100000; i++) {
      objectMapper.readValue(bytes, Person.class);
    }
    long end = System.nanoTime();
    System.out.println("time cost = " + (end - start) / 1000000.0 + "ms");
  }
}

以上代码中,我们首先创建了一个 Person 对象,并将其序列化成了一个 json 数据。然后使用 readValue 方法将其转化成一个 Person 对象。在测试中,我们使用了一个 for 循环,重复地执行了 100000 次该操作,并记录了执行时间。

这个测试的结果是,执行 100000 次序列化和反序列化操作的时间为 610ms 左右。极大地证明了 Jackson 的性能在处理 JSON 数据时的优越性。

示例

示例 1:处理复杂的 json 数据

假设你要解析一份包含多个复杂对象的 JSON 数据,比如:

[
  {
    "name": "John",
    "age": 30,
    "address": {
      "street": "104 Langton Street",
      "city": "San Francisco",
      "state": "CA",
      "zipCode": "94103"
    }
  },
  {
    "name": "Jane",
    "age": 25,
    "address": {
      "street": "30 Washington Street",
      "city": "Boston",
      "state": "MA",
      "zipCode": "02108"
    }
  }
]

以下是处理该 JSON 数据的示例代码:

public class Address {
  private String street;
  private String city;
  private String state;
  private String zipCode;

  public String getStreet() {
    return street;
  }

  public void setStreet(String street) {
    this.street = street;
  }

  public String getCity() {
    return city;
  }

  public void setCity(String city) {
    this.city = city;
  }

  public String getState() {
    return state;
  }

  public void setState(String state) {
    this.state = state;
  }

  public String getZipCode() {
    return zipCode;
  }

  public void setZipCode(String zipCode) {
    this.zipCode = zipCode;
  }

  @Override
  public String toString() {
    return "Address{" +
            "street='" + street + '\'' +
            ", city='" + city + '\'' +
            ", state='" + state + '\'' +
            ", zipCode='" + zipCode + '\'' +
            '}';
  }
}

public class Person {
  private String name;
  private int age;
  private Address address;

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public int getAge() {
    return age;
  }

  public void setAge(int age) {
    this.age = age;
  }

  public Address getAddress() {
    return address;
  }

  public void setAddress(Address address) {
    this.address = address;
  }

  @Override
  public String toString() {
    return "Person{" +
            "name='" + name + '\'' +
            ", age=" + age +
            ", address=" + address +
            '}';
  }
}

public class JacksonDemo {
  public static void main(String[] args) throws IOException {
    String json = "[\n" +
            "  {\n" +
            "    \"name\": \"John\",\n" +
            "    \"age\": 30,\n" +
            "    \"address\": {\n" +
            "      \"street\": \"104 Langton Street\",\n" +
            "      \"city\": \"San Francisco\",\n" +
            "      \"state\": \"CA\",\n" +
            "      \"zipCode\": \"94103\"\n" +
            "    }\n" +
            "  },\n" +
            "  {\n" +
            "    \"name\": \"Jane\",\n" +
            "    \"age\": 25,\n" +
            "    \"address\": {\n" +
            "      \"street\": \"30 Washington Street\",\n" +
            "      \"city\": \"Boston\",\n" +
            "      \"state\": \"MA\",\n" +
            "      \"zipCode\": \"02108\"\n" +
            "    }\n" +
            "  }\n" +
            "]";

    ObjectMapper objectMapper = new ObjectMapper();
    JavaType collectionType = objectMapper.getTypeFactory().constructCollectionType(List.class, Person.class);
    List<Person> persons = objectMapper.readValue(json, collectionType);

    for (Person person : persons) {
      System.out.println(person);
    }
  }
}

示例 2:序列化和反序列化 Map

Jackson 还可以处理序列化和反序列化 Map 对象。以下是一个简单的示例代码:

public static void main(String[] args) throws IOException {
    String json = "{\"name\":\"Tony\",\"age\":30,\"address\":{\"city\":\"San Francisco\",\"state\":\"CA\"}}";

    ObjectMapper objectMapper = new ObjectMapper();
    JavaType mapType = objectMapper.getTypeFactory().constructMapType(HashMap.class, String.class, Object.class);
    Map<String, Object> map = objectMapper.readValue(json, mapType);
    System.out.println(map);

    String json2 = objectMapper.writeValueAsString(map);
    System.out.println(json2);
}

该代码中,我们先定义了一个包含复杂元素的 Map 对象,然后使用 readValue 方法将其转换成了一个 Map 对象,并将其打印出来。接着,我们再把该 Map 对象序列化成一个 json 字符串,并将其打印出来。

本文标题为:详解Jackson 使用以及性能介绍

基础教程推荐