杰克逊无法用枚举字段反序列化不可变对象
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
,而是因为 Lombok
和 Jackson
在这种情况下不能一起工作。
反序列化为不可变 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;
}
}
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
,而是因为 Lombok
和 Jackson
在这种情况下不能一起工作。
反序列化为不可变 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;
}
}