Jackson 解串器默认是如何工作的

Posted

技术标签:

【中文标题】Jackson 解串器默认是如何工作的【英文标题】:How does Jackson deserializer work by default 【发布时间】:2020-02-21 15:49:06 【问题描述】:

我正在使用Spring-boot 2.1.6,我有DTO

@AllArgsConstructor
@Builder
@Data // setters, getters, others
@NoArgsConstructor
public class ExampleDto 
    private String fieldOne;
    private String fieldsTwo;


我真的需要这么多Lombok 注释吗?通过HTTP 连接(微服务)反序列化时,Jackson 默认使用哪个? 我想只有NoArgsConstructor + setters 可以吗?还是它使用 reflection 并且只提供 no-arg-constructor 就可以了?

是否可以选择将Jackson 的行为更改为仅使用AllArgsConstructorbuilder? 我在日志中看到我的应用使用Jackson 反序列化内容。

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
    <version>2.8.8</version>
    <scope>provided</scope>
</dependency>

 <dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jdk8</artifactId>
</dependency>

<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
</dependency>

编辑:

我的问题与Can't make Jackson and Lombok work together 不同,因为它有效。

【问题讨论】:

Can't make Jackson and Lombok work together的可能重复 @Strelok 我的问题与Can't make Jackson and Lombok work together 不同,因为它可以协同工作。 也许您应该阅读实际链接的问题,因为投票最多的答案告诉您如何使用 Lombok 建设者????。你几乎没有尝试 我的问题部分是关于默认情况下Jackson 的工作原理我没有看到那里提到的。 【参考方案1】:

Jackson 使用默认(无参数)构造函数创建对象,然后使用 setter 设置值。所以你只需要@NoArgsConstructor 和@Setter。

【讨论】:

其他问题是:Is there an option to change behaviour of Jackson to use only AllArgsConstructor or builder? @tryingHard 我认为这可能会对您有所帮助octoperf.com/blog/2018/02/01/polymorphism-with-jackson 另外,如果你想修改任何字段,你可以使用自己的设置器,而不是使用从 lambok 自动生成的设置器【参考方案2】:

根据this tutorialjackson 搜索getter 和setter 方法。此外,要创建该类型的对象,还需要默认构造函数。所以基本上你需要一个满足java bean 约定的类。

长话短说:您需要 @Data 用于 getter 和 setter 方法,@NoArgsConstructor 用于默认构造函数以满足 bean 约定。 jackson 不需要@AllArgsConstructor@Builder

【讨论】:

其他问题是:Is there an option to change behaviour of Jackson to use only AllArgsConstructor or builder? 我不认为有这样的选择,虽然我不太确定。但是只使用@AllArgsConstructorjackson 至少需要知道构造函数中元素的顺序,我认为这应该是不可能的。所以这只是一个有根据的猜测,但我认为这是不可能的。【参考方案3】:

既然您使用的是 Spring Boot,那么在某处应该有一个用 @Configuration 注释的 Jackson 配置类。像这样的东西应该可以在不需要任何注释的情况下为您的 Java bean 启用序列化

@Configuration
public class JacksonConfiguration 

   @Bean
   public ObjectMapper objectMapper() 
      ObjectMapper mapper = new ObjectMapper();
      objectMapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);
      return mapper;
   


【讨论】:

【参考方案4】:

Jackson 反序列化默认使用对象的 no-args 构造函数setters。因此,使用 Lombok,您至少需要:

@NoArgsConstructor
@Setter
public class ExampleDto 
    private String fieldOne;
    private String fieldsTwo;

(请注意,如果您曾经序列化,那么您至少需要一个 @Getter)。

有一个选项可以覆盖 Jackson 的默认反序列化以使用 Lombok 构建器。这包含在Can't make Jackson and Lombok work together 的最佳答案中(正如其他人所提到的)。即

@Builder
@Data
@JsonDeserialize(builder = ExampleDto.ExampleDtoBuilder.class)
public class ExampleDto 
    private String fieldOne;
    private String fieldsTwo;


@JsonPOJOBuilder(withPrefix = "") 
public static class ExampleDtoBuilder 


【讨论】:

【参考方案5】:

Jackson 使用默认的 NoArgsConstructor 和 Setter。

如果您不提供 Setter,jackson 将使用反射设置值。见-How does jackson set private properties without setters?

【讨论】:

以上是关于Jackson 解串器默认是如何工作的的主要内容,如果未能解决你的问题,请参考以下文章

将值注入Jackson转换器/解串器

杰克逊解串器优先级?

加串器解串器

串行解串器 SerDes

改造 + GSON 解串器

DC平衡双向控制解串器 转接IC GM8914:FPD-LINK III转LVTTL芯片