![](/img/trans.png)
[英]IDE does not show getters and setters generated by Lombok for a Jackson annotated class
[英]Immutable Lombok annotated class with Jackson
创建类的首选方法是什么
最好,我会喜欢这样的工作:
@Data(onConstructor = @__(@JsonCreator))
然后将所有字段设为private final
。 但是,这甚至无法编译(我不确定为什么)。 使用
@AllArgsConstructor(onConstructor = @__(@JsonCreator))
将编译但只产生
InvalidDefinitionException: No serializer found for class
添加构造函数属性:
lombok.config
适当的位置创建lombok.config
文件: lombok.anyConstructor.addConstructorProperties = true
@Value
注释添加到您的类中以使其不可变然后杰克逊的序列化和反序列化按预期工作。
这种方法:
编辑:2020-08-16
@Builder
与@Value
@Builder
使用会导致此解决方案失败。 (感谢下面来自@guilherme-blanco 的评论。)但是,如果您还添加了例如@AllArgsConstructor
它仍然可以按预期工作。编辑:2021-08-19
lombok.config
文件时,除非您进行重新构建(先清理然后构建),否则不会获取更改。 我已经被这件事抓住了几次。@Jacksonized
注释解决方案是另一种为注释的特定类实现所需结果的方法。 但是,我个人更喜欢不需要记住对用于反序列化的每个类进行注释。 使用lombok.config
消除了这种开销。您可以使用 Lombok 的@Builder
注释为您的不可变 POJO 类生成构建器。 但是让杰克逊的反序列化可以使用 Lombok 生成的构建器有点棘手。
@JsonDeserialize(builder = ...)
注释您的 POJO 类以告诉 Jackson 哪个是要使用的构建器类。@JsonPOJOBuilder(withPrefix = "")
告诉杰克逊其setter方法的方法不下手with
。示例:
一个不可变的 POJO 类:
@Data
@Builder(builderClassName = "PointBuilder")
@JsonDeserialize(builder = Point.PointBuilder.class)
public class Point {
private final int x;
private final int y;
@JsonPOJOBuilder(withPrefix = "")
public static class PointBuilder {
// Lombok will add constructor, setters, build method
}
}
这是一个用于验证序列化/反序列化的 JUnit 测试:
public class PointTest extends Assert {
private ObjectMapper objectMapper = new ObjectMapper();
@Test
public void testSerialize() throws IOException {
Point point = new Point(10, 20);
String json = objectMapper.writeValueAsString(point);
assertEquals("{\"x\":10,\"y\":20}", json);
}
@Test
public void testDeserialize() throws IOException {
String json = "{\"x\":10,\"y\":20}";
Point point = objectMapper.readValue(json, Point.class);
assertEquals(new Point(10, 20), point);
}
}
截至 2020 年 10 月 15 日( Lombok v1.18.16 ),您应该能够简单地使用@Jacksonized
注释。
@Jacksonized @Builder @JsonIgnoreProperties(ignoreUnknown = true) public class JacksonExample { private List<Foo> foos; }
如链接文档中所述,此注释:
@JsonIgnoreProperties
),以及builder().withField(field)
与builder.field(field)
与 Lombok 中配置的前缀对齐。通过参考Joseph K. Strauss 的回答,我想出了以下解决方案。
对我有用的普通 lombok 注释看起来像这样。 以下注释为您提供了具有构建器的不可变类,可以由 Jackson 序列化和反序列化。
@Data
@Setter(AccessLevel.NONE)
@Builder(toBuilder = true)
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class Clazz {
private String field;
}
我更喜欢这个解决方案,因为它不需要额外的Jackson 特定注释,也不需要额外的lombok 特定文件
另一种不那么冗长的替代方案:
@Data
@Setter(AccessLevel.NONE)
public class Clazz {
private String field;
}
当然,您仍然可以有一些直接修改字段的私有方法,但是在@Data POJO 中甚至不太可能有任何实际代码,因此希望不会发生这种情况。
免责声明:这将产生不让常规 Java 代码创建对象的副作用(可能是有益的),因为只有一个没有修改器的默认构造函数。 为了允许正常构建,您还需要 2 个注释:
@Data
@AllArgsConstructor
@NoArgsConstructor
@Setter(AccessLevel.NONE)
public class Clazz {
private String field;
}
为您的 pojo 尝试以下一组注释:
@Value
@NoArgsConstructor(force = true, access = AccessLevel.PRIVATE)
@AllArgsConstructor
为 Jackson 配置不可变类的最简单方法是使用@Value
注释: @Value
和@Jacksonized
:
@Jacksonized
@Builder
@Value
class Foo {
}
我刚刚用这种方式解决了它:
@Value
@Builder(setterPrefix = "with")
@JsonDeserialize(builder = Clazz.ClazzBuilder.class)
public class Clazz {
private String field;
}
在这种情况下,您必须使用像withField(...)
这样的构建器方法,这是 jackson 使用的默认行为。
在 pom.xml 中添加 Jackson Dataformat 依赖项后,Thomas Fritsch 的回答与 Spring Boot 完美配合。
@Data
@Builder(builderClassName = "PointBuilder")
@JsonDeserialize(builder = Point.PointBuilder.class)
public class Point {
private final int x;
private final int y;
@JsonPOJOBuilder(withPrefix = "")
public static class PointBuilder {
// Lombok will add constructor, setters, build method
}
}
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.dataformat/jackson-dataformat-xml -->
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.