让@JsonAnySetter与@Value龙目岛一起使用

问题描述 投票:2回答:1

我有一个具有很多属性(〜80个属性)的json对象,我想在POJO中反序列化而不手动创建所有属性。我可以通过将@JsonAnySetterMap属性一起使用来实现此目的,如here所述。

现在,我想通过使用Lombok使我的POJO不变来完成这项工作。我试过了,但是它只会反序列化idcode属性。关于如何使它起作用的任何想法吗?

@Value
@Builder
@EqualsAndHashCode
@JsonDeserialize(builder = Product.ProductBuilder.class)
class Product {

   @JsonProperty
   private String id;
   @JsonProperty
   private String code;
   @Getter(AccessLevel.NONE)
   @Builder.Default
   @JsonProperty
   private Map<String, Optional<Object>> any = new HashMap<>();

   @JsonAnyGetter
   public  Map<String, Optional<Object>> getAny(){
       return this.any;
   }

   @JsonAnySetter
   public void setAny(String key, Optional<Object> value){
      this.any.put(key, value);
   }

}
java jackson lombok
1个回答
1
投票

目前,这需要对生成的生成器类进行一些自定义。 (在此答案的结尾,我将展望下一个龙目岛版本中的这一点将如何改善。)

自定义lombok构建器可以通过简单地将其内部类头添加到您的类中来完成。 Lombok检测到已经存在一个构建器类,并仅添加所有尚不存在的东西。这意味着您可以添加自己的方法,并且如果这些方法的名称与lombok会生成的方法的名称相同,则lombok会跳过此方法。

[使用这种方法,我们将构建器的setter方法替换为“ any”,并向其中添加所需的@JsonAnySetter。如果顺序相关,我将LinkedHashMap用作地图;您可以使用常规的HashMap

此外,我们替换build()方法以确保提供给构造函数的映射是不可变的。我在这里使用番石榴的ImmutableMap。这将使创建的实例成为不可变的值。

@Value
@Builder
@JsonDeserialize(builder = Product.ProductBuilder.class)
class Product {

    @JsonProperty
    private String id;
    @JsonProperty
    private String code;

    @Getter(onMethod_ = @JsonAnyGetter)
    private Map<String, Object> any;

    @JsonPOJOBuilder(withPrefix = "")
    public static class ProductBuilder {
        @JsonAnySetter
        public ProductBuilder any(String anyKey, Object anyValue) {
            if (this.any == null) {
                this.any = new LinkedHashMap<String, Object>();
            }
            this.any.put(anyKey, anyValue);
            return this;
        }

        public Product build() {
            return new Product(id, code, any == null ? ImmutableMap.of() : ImmutableMap.copyOf(any));
        }

    }
}

Lombok使用@Singular批注内置了对不可变地图的支持。更重要的是,它创建了Jackson设置“任何值”所需的确切方法,只是缺少@JsonAnySetter注释。不幸的是,@Singular不支持自定义,因此我们无法在此方法中添加@JsonAnySetter。有一些ongoing work旨在自动将Jackson注释(包括@JsonAnySetter)复制到构建器的setter方法中。在这种情况下,这将完全消除对构建器定制的需求。释放此功能后,我将更新此答案。

© www.soinside.com 2019 - 2024. All rights reserved.