【发布时间】:2019-03-13 11:27:07
【问题描述】:
背景:我在 spring-admin 项目中发现“功能失调”代码:“无法构造注册实例(没有创建者,如默认构造,存在)”。所以我写了自定义反序列化器并报告了这个问题。但报告被拒绝,因为它据称有效。重新测试后,它现在似乎可以工作了。没有意义。所以我想知道为什么该代码有效。
但这就是问题所在。当我编写类似的测试类时,它在我的项目中不起作用。即使我从字面上获取“正在工作的”注册类的代码,并在自己的项目中尝试它,也根本不会反序列化。然后,使用几乎相同的类,它可以工作。这没有任何意义。
以下帖子解释了 lombok-jackson 组合的工作原理,但在这里不起作用。我完全困惑,这是令人难以置信的荒谬情况,(不必要的)简化会产生极好的复杂性。不过我想了解一下,以后还能遇到这种情况。
Jackson Deserialization Fails because of non-default constructor created by lombok
所以有一些易于使用的东西:这里我们有漂亮且工作的纯杰克逊:
public class TestTO_pureJackson {
private final String a;
private final String b;
@JsonCreator
private TestTO_pureJackson(@JsonProperty("a") String a, @JsonProperty("b") String b) {
this.a = a;
this.b = b;
}
}
在这里,我们没有处理 lombok 等效项(即使我删除了一个字段,因此它与后一个示例“相同”):
@lombok.Data
public class TestTO {
private final String a;
private final String b;
@lombok.Builder(builderClassName = "Builder")
private TestTO(String a, String b) {
this.a = a;
this.b = b;
}
public static TestTO.Builder create(String a) {
return builder().a(a);
}
}
我们正在尝试反序列化:
{"a": "a", "b": "b"}
谁能理解幕后的魔力,并帮助我理解这里出了什么问题?
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.2</version>
<scope>provided</scope>
</dependency>
为了让它变得更加荒谬(你真的看到 TestTO 有什么显着的不同吗???),下面的代码可以工作:
@lombok.Data
public class Pair {
private final String left;
private final String right;
@lombok.Builder(builderClassName = "Builder")
private Pair(String pairId) {
left = pairId.substring(0, 3).toUpperCase(Locale.US);
right = pairId.substring(3).toUpperCase(Locale.US);
}
}
主要方法:
public class PairTest {
public static final String DATA = "[\"btcusd\",\"ltcusd\",\"ltcbtc\"]";
public static void main(String[] args) throws IOException {
ObjectMapper objectMapper = new ObjectMapper();
Pair[] pairs = objectMapper.readValue(DATA, Pair[].class);
for (Pair pair : pairs) {
System.out.println(pair);
}
}
}
谁能看到,为什么 2 个几乎相同的 TO 类的行为不同?
【问题讨论】:
-
在任何项目中是否有
lombok.config?如果有,它的内容是什么? -
yes: config.stopBubbling=true lombok.accessors.chain=true 但我担心这可能是由于违反 java bean 规范引起的,所以我也尝试了没有 lombok.accessors.chain=true ,它的行为也是一样的。