这是我遇到的一个问题的简化版本。给定这些类:
@Value
@Jacksonized
@Builder(builderClassName = "Builder", setterPrefix = "with")
public class Limits {
Limit minimum;
Limit maximum;
}
@Value
@Jacksonized
@Builder(builderClassName = "Builder", setterPrefix = "with")
public class Limit {
@JsonValue
String value;
}
和这个代码:
Limits limits = Limits.builder()
.withMinimum(Limit.builder().withValue("One-Day").build())
.withMaximum(Limit.builder().withValue("One-Year").build())
.build();
System.out.println(objectMapper.writeValueAsString(limits));
它按预期工作,并给出以下输出:
{
"minimum": "One-Day",
"maximum": "One-Year"
}
但是,当我尝试反序列化相同的JSON字符串时,如下所示:
String json = """
{"minimum":"One-Day","maximum":"One-Year"}
""";
objectMapper.readValue(json, Limits.class);
出现以下错误:
Cannot construct instance of `Limit$Builder` (although at least one Creator exists):
no String-argument constructor/factory method to deserialize from String value ('One-Day')
at [Source: (String)"{"minimum":"One-Day","maximum":"One-Year"}"; line: 1, column: 12]
有没有一种方法可以在不改变数据模型或JSON的情况下使它工作?
我尝试将@JsonCreator
添加到Limit
的构建器中,如下所示,但出现相同的错误
@Value
@Jacksonized
@Builder(builderClassName = "Builder", setterPrefix = "with")
public class Limit {
@JsonValue
String value;
public static final class Builder {
@JsonCreator
public Builder withValue(String value) {
this.value = value;
return this;
}
}
}
感谢任何关于我可能错过的东西的输入。
1条答案
按热度按时间mqkwyuun1#
Jackson不支持
@JsonCreator
与构建器的组合。@JsonCreator
基本上是这样说的:带注解的方法构造了一个新示例,将JSON值作为实参传递给它的单个形参,但这对构建器不起作用,因为没有这样的方法可以同时完成这两个任务(有两个独立的方法,一个用于接收JSON值,另一个用于构造示例)。但是,在您的情况下,有一个简单的变通方法,不会失去不变性。只需将
@JsonCreator
放在一个全参数构造函数上,如下所示:如果您愿意,可以保留
@Builder
,但没有必要这样做。