Lombok + Jackson 不可变

Posted

技术标签:

【中文标题】Lombok + Jackson 不可变【英文标题】:Lombok + Jackson immutables 【发布时间】:2018-07-16 14:55:34 【问题描述】:

将我的项目更新到 Spring Boot 1.5.10 后 龙目岛停止与杰克逊正常工作。 我的意思是创建不可变 DTO,当我的对象中的字段名称与 json 请求中的字段不同时:

@Value
@Builder
public class MyImmutableDto implements Serializable 

    @JsonProperty("other-field-1-name")
    private final BigDecimal myField1;

    @JsonProperty("other-field-2-name")
    private final String myField2;

    and a lot of fields there...

所以,在将 Spring Boot 更新到 1.5.10 后,此代码不起作用,我需要像这样配置 lombok:

lombok.anyConstructor.addConstructorProperties = true

有没有人知道在没有这个 lombok 修复的情况下使用 jackson + lombok 创建此类对象的任何其他方法? 我可以使用以下代码代替此修复程序:@JsonPOJOBuilder@JsonDeserialize(builder = MyDto.MyDtoBuilder.class):

@Value
@Builder
@JsonDeserialize(builder = MyDto.MyDtoBuilder.class)
public class MyDto implements Serializable 

    // @JsonProperty("other-field-1-name")    // not working
    private final BigDecimal myField1;

    private final String myField2;
    private final String myField3;
    and a lot of fields there...

    @JsonPOJOBuilder(withPrefix = "")
    public static final class MyDtoBuilder 
    

但它不适用于@JsonProperty("other-field-1-name")。 Ofc,它可以通过简单的@JsonCreator 来完成,但也许有一些方法可以通过一些构造函数/jackson 注释将它与 lombok 一起使用?

【问题讨论】:

我没有得到解决原始问题的第一种方法,所以我求助于第二种方法,发现(当然)字段上的杰克逊注释不会延续到构建器方法,所以我我对即将发生的事情感兴趣。 @simon 发布了一个对我有用的答案。只是想确认您遇到此问题时使用的版本 您可以使用具有不变性的 Lombok + Jackson:answer 可以同时使用lombok builder和jackson:***.com/a/48801237/4944734 【参考方案1】:

所以这不是完全相同的情况,但这适用于我的问题。我需要构建器上的@JsonDeserialize 注释,将它放在构建器上可以显式解决问题(以样板代码为代价)。至少我不需要输入构建器的其余部分。

@Value
@Builder
@JsonDeserialize(builder = ProductPrice.ProductPriceBuilder.class)
public class ProductPrice 

    @JsonSerialize(using = MoneySerializer.class)
    @JsonDeserialize(using = MoneyDeserializer.class)
    Money price;

    Duration rentalLength;

    Period recurrence;

    @JsonPOJOBuilder(withPrefix = "")
    public static class ProductPriceBuilder
        @JsonDeserialize(using = MoneyDeserializer.class)
        public ProductPrice.ProductPriceBuilder price(Money price) 
            this.price = price;
            return this;
          
    

【讨论】:

【参考方案2】:

考虑到这个问题是在 2017 年 1 月之后提出的,我假设您可能已经升级了您的 Lombok 1.16.20以及 Spring Boot 版本。并且仍在使用 JDK 8

您可以更新您的 Spring Boot 版本,但可能希望将您的 Lombok 版本保留在 1.16.18。这将让您通过构建器工作来实现额外的自定义和反序列化。也就是说,只要您没有使用任何新的 lombok 注释。

在 1.16.20 中进行了大量工作,特别是解决 JDK 9 中的重大更改,这些更改可能会导致 JDK 8 上的问题。

1.16.20 @Data object no longer constructable for jackson?

【讨论】:

以上是关于Lombok + Jackson 不可变的主要内容,如果未能解决你的问题,请参考以下文章

Jackson 私有构造函数,JDK 9+,Lombok

在不可变请求类中使用 Lombok

IDE 不显示 Lombok 为 Jackson 注释类生成的 getter 和 setter

Jackson 使用 mixin 对 Lombok @Builder 类进行反序列化不起作用

java中是啥是不可变对象和可变对象

scala数据结构与可变不可变