【问题标题】:Make @JsonAnySetter work with @Value Lombok使@JsonAnySetter 与@Value Lombok 一起工作
【发布时间】:2020-04-12 00:32:17
【问题描述】:

我有一个带有很多属性(约 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】:

    2021-02-01 更新:Lombok v1.18.16

    从 v1.18.16 开始,Lombok 会自动将 @JsonAnySetter 复制到 builder 中的 @Singular 方法中。结合@Jacksonized,您可以简单地使用此代码:

    @Value
    @Jacksonized
    @Builder
    class Product {
        private String id;
        private String code;
    
        @JsonAnySetter
        @Singular("any")
        private Map<String, Object> any;
    }
    

    旧龙目岛版本

    对于以前的 Lombok 版本,这需要对生成的构建器类进行一些自定义。

    可以通过简单地将其内部类头添加到您的类来自定义lombok builder。 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));
            }
    
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-11-26
      • 1970-01-01
      • 2018-05-20
      • 2018-10-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多