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
的行为更改为仅使用AllArgsConstructor
或builder
?
我在日志中看到我的应用使用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?
我不认为有这样的选择,虽然我不太确定。但是只使用@AllArgsConstructor
jackson 至少需要知道构造函数中元素的顺序,我认为这应该是不可能的。所以这只是一个有根据的猜测,但我认为这是不可能的。【参考方案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 解串器默认是如何工作的的主要内容,如果未能解决你的问题,请参考以下文章