杰克逊无法用枚举字段反序列化不可变对象

Jackson unable to deserialize immutable object with enum field

Spring 使用 Jackson 2.12.4 启动 2.5.4

给定以下简化枚举...

@AllArgsConstructor
@Getter
public enum PaymentMethod {
  CREDITCARD(1);

  private long id;
}

...和一个应使用 Jackson 反序列化的请求对象:

@NoArgsConstructor
@Getter
@Setter
public class PaymentRequest {

    @JsonProperty(value = "paymentMethod")
    private PaymentMethod paymentMethod;
}

这很好用。现在,我想让请求对象不可变,所以我将其更改为:

@RequiredArgsConstructor
@Getter
public class PaymentRequest {

    @JsonProperty(value = "paymentMethod")
    private final PaymentMethod paymentMethod;
}

但是这个变体失败了:

Cannot construct instance of 'PaymentRequest' (no Creators, like default constructor, exist): cannot deserialize from Object value (no delegate- or property-based Creator)

反序列化枚举时,这是 Jackson 的一些限制吗?

这个问题不是因为参数是 Enum,而是因为 LombokJackson 在这种情况下不能一起工作。

反序列化为不可变 class 时,我们需要使用 Jackson 注释明确提及。通常我们注释构造函数。但在这种情况下,构造函数是由 Lombok 创建的,并且 Lombok 不添加这些注释。

简单的解决方法是,删除 @RequiredArgsConstructor 注释并自己创建构造函数。然后将构造函数注释为@JsonCreator。像这样,

@Getter
public class PaymentRequest {

    @JsonProperty(value = "paymentMethod")
    private final PaymentMethod paymentMethod;

    @JsonCreator
    public PaymentRequest(PaymentMethod paymentMethod) {
        this.paymentMethod = paymentMethod;
    }
}