Jackson第三方模块Module说明

2021-10-23  本文已影响0人  virtual灬zzZ

本文主要讲解全由官方主导维护的三个模块,是实际应用中使用得最广泛的、和我们工作密切相关的模块们:

jackson-module-parameter-names

 <dependency>
      <groupId>com.fasterxml.jackson.module</groupId>
      <artifactId>jackson-module-parameter-names</artifactId>
      <version>${jackson.version}</version>
</dependency>

@Test
public void fun1() throws JsonProcessingException {
    JsonMapper mapper = new JsonMapper();

    String jsonStr = "{\"name\":\"YourBatman\",\"age\":18}";
    Person person = mapper.readValue(jsonStr, Person.class);
    System.out.println(person);
}


@Getter
@Setter
@ToString
public class Person {
    private String name;
    private Integer age;

    public Person(String name, Integer age) {
        this.name = name;
        this.age = age;
    }
}

运行报错如下

com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `com.youtbatman.java...

这个报错很容易理解,因为没有找到合适的构造器来创建Person,怎么破?可以这样做

@JsonCreator
public Person(@JsonProperty("name") String name,@JsonProperty("age") Integer age) {
    this.name = name;
    this.age = age;
}

再次运行正常输出

Person(name=YourBatman, age=18)

在使用该注解时有如下注意事项:

  1. @JsonProperty是必须的,且value属性也是必须填写的
  2. 实验证明value属性写得不一样也没关系,但仍建议保持和JSON串的一致
  3. @JsonProperty最好给构造器的每个参数都标记,上(否则容易拋错),标记好@JsonP roperty后的构造器,@JsonCreator 并不是必须的了,但也建议显示的标注上

可以看到使用这种方式处理还是较为繁琐:需要使用大量的注解来标注才行。那么,jackson-module-parameter-names就拯救了这一切,让Jackson的处理得更加的优雅

// 给JsonMapper显示注册上此模块
mapper.registerModule(new ParameterNamesModule());


// POJO无需给与任何注册
public Person(String name, Integer age) {
    this.name = name;
    this.age = age;
}

再次运行,程序正常输出

Person(name=YourBatman, age=18)

注意:如果你这么来用没有效果(依旧报错),请检查你是否基于Java8+编译,并且确认是否开启了-parameters这个编译参数

jackson-datatype-jdk8

<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jdk8</artifactId>
    <version>${jackson.version}</version>
</dependency>

顾名思义,它提供了对Java8新类型的-些支持,如: Optional/0pt ionalInt/0pt ionalLong/0pt ionalDouble等以及St ream/ IntStream/LongSt ream/DoubleStream等.

@Test
public void fun1() throws JsonProcessingException {
    JsonMapper mapper = new JsonMapper();

    System.out.println("注册JDK8模块前:");
    mapper.writeValueAsString(OptionalInt.of(1));
    mapper.writeValueAsString(Optional.of("YourBatman"));
    mapper.writeValueAsString(IntStream.of(1,2,3));
    mapper.writeValueAsString(Stream.of("1","2","3"));
}

注册JDK8模块前:

{"asInt":1,"present":true}
{"present":true}
{"parallel":false}
{"parallel":false}

注册上jackson-datatype-jdk8模块后

mapper.registerModule(new Jdk8Module())

再次运行程序输出为:

注册JDK8模块后:

"YourBatman"
[1,2,3]
["1","2","3"]

jackson-datatype-jsr310

<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
    <version>${jackson.version}</version>
</dependency>

而该模块JSR310支持到了时间类型的序列化、反序列化,让处理这些类型起来都变得更加的优雅。

@Test
public void fun1() throws JsonProcessingException {
    JsonMapper mapper = new JsonMapper();
   
    System.out.println(mapper.writeValueAsString(LocalDateTime.now()));
    System.out.println(mapper.writeValueAsString(LocalDate.now()));
    System.out.println(mapper.writeValueAsString(LocalTime.now()));
    System.out.println(mapper.writeValueAsString(Instant.now()));
}
{"year":2021,"month":"MARCH","nano":398000000,"monthValue":3,"dayOfMonth":12,"hour":23,"minute":44,"second":37,"dayOfYear":71,"dayOfWeek":"FRIDAY","chronology":{"id":"ISO","calendarType":"iso8601"}}
{"year":2021,"month":"MARCH","monthValue":3,"dayOfMonth":12,"chronology":{"id":"ISO","calendarType":"iso8601"},"era":"CE","dayOfYear":71,"dayOfWeek":"FRIDAY","leapYear":false}
{"hour":23,"minute":44,"second":37,"nano":528000000}
{"epochSecond":1615563877,"nano":530000000}

注册jackson-datatype-jsr310模块后

mapper.registerModule(new JavaTimeModule());

运行结果如下

[2021,3,12,23,45,11,818000000]
[2021,3,12]
[23,45,11,849000000]
1615563911.849000000
上一篇 下一篇

猜你喜欢

热点阅读