Java 带Jackson的不可变Lombok注释类
创建类的首选方法是什么Java 带Jackson的不可变Lombok注释类,java,json,jackson,lombok,jackson-databind,Java,Json,Jackson,Lombok,Jackson Databind,创建类的首选方法是什么 不变的 可以使用Jackson进行序列化/反序列化 可读性强,样板文件水平低 最好是,我希望这样的工作: @Data(onConstructor = @__(@JsonCreator)) 然后将所有字段设置为private final。然而,这甚至没有编译(我不知道为什么)。使用 将编译,但只生成 InvalidDefinitionException: No serializer found for class 可以使用Lombok注释为不可变的POJO类生成生成
- 不变的
- 可以使用Jackson进行序列化/反序列化
- 可读性强,样板文件水平低
@Data(onConstructor = @__(@JsonCreator))
然后将所有字段设置为private final
。然而,这甚至没有编译(我不知道为什么)。使用
将编译,但只生成
InvalidDefinitionException: No serializer found for class
可以使用Lombok注释为不可变的POJO类生成生成器。
但是通过Jackson的反序列化使Lombok生成的生成器可用有些棘手
- 您需要使用 告诉Jackson要使用哪个生成器类
- 您需要使用
要告诉Jackson它的setter方法确实是而不是,请从
开始with
@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);
}
}
另一个不那么冗长的选择:
@Data
@Setter(AccessLevel.NONE)
public class Clazz {
private String field;
}
当然,您仍然可以有一些直接修改字段的私有方法,但在@datapojo中甚至不太可能有任何实际代码,因此希望不会发生这种情况
免责声明:
这将产生一个副作用(可能是有益的),即不让常规Java代码创建对象,因为只有一个默认构造函数,没有任何变体。为了允许正常构造,您还需要另外两个注释:
@Data
@AllArgsConstructor
@NoArgsConstructor
@Setter(AccessLevel.NONE)
public class Clazz {
private String field;
}
添加构造函数属性:
- 使用以下行创建
文件:lombok.config
lombok.anyConstructor.addConstructorProperties=true
- 将lombok
注释添加到类中以使其不可变@Value
- 符合标准
- 与上一个顶级答案相比,具有更少的样板文件位置
- 工作日及以后
- 注意:将
与@Builder
一起使用会导致此解决方案失败。(感谢下面@guilherme blanco的评论。) 但是,如果您还添加了例如@Value
,它仍能按预期工作@allargsconstuctor
@Data
@Setter(AccessLevel.NONE)
@Builder(toBuilder = true)
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class Clazz {
private String field;
}
我更喜欢这个解决方案,因为它不需要额外的,也不需要额外的托马斯·弗里奇(Thomas Fritsch)的答案在pom中添加Jackson Dataformat依赖项后,与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>
@数据
@生成器(builderClassName=“PointBuilder”)
@JsonDeserialize(builder=Point.PointBuilder.class)
公共课点{
私人最终int x;
私人终审法院;
@JsonPOJOBuilder(前缀为“”)
公共静态类PointBuilder{
//Lombok将添加构造函数、设置器和构建方法
}
}
com.fasterxml.jackson.dataformat
jackson数据格式xml
尝试以下pojo注释集:
@Value
@NoArgsConstructor(force = true, access = AccessLevel.PRIVATE)
@AllArgsConstructor
我刚刚用这种方法解决了这个问题:
@Value
@Builder(setterPrefix = "with")
@JsonDeserialize(builder = Clazz.ClazzBuilder.class)
public class Clazz {
private String field;
}
在这种情况下,您必须使用构建器方法,如withField(…)
,这是jackson使用的默认行为。从2020年10月15日起(),您应该能够简单地使用注释
@Jacksonized@Builder
@JsonIgnoreProperties(ignoreUnknown=true)
公共类Jacksone示例{
私人名单;
}
如链接文档中所述,此注释:
- 将Jackson配置为使用生成器进行反序列化
- 将特定于字段的配置从注释类向下复制到生成的生成器(例如
),以及@JsonIgnoreProperties
- 将生成器方法(例如
vsbuilder().withField(field)
上使用的Jackson前缀与Lombok中配置的前缀对齐builder.field(field)
@Jacksonized
@建筑商
@价值观
福班{
}
我使用这种方法已经有一段时间了,而且非常非常有效。一个非常小的改进是,我总是给我的构建器类命名\u builder。这样,当我复制粘贴以创建新类等时……我不必记得更改builderClassName中的字符串。我以前调用过类构建器(不带下划线),但在处理内部静态类时,这与@Builder注释类有奇怪的冲突。注意:这种方法不能与@Builder结合使用。谢谢。但是看起来:我们能把这个答案排在第一位吗?它的效果很好:)
@Value
@Builder(setterPrefix = "with")
@JsonDeserialize(builder = Clazz.ClazzBuilder.class)
public class Clazz {
private String field;
}
@Jacksonized @Builder
@JsonIgnoreProperties(ignoreUnknown = true)
public class JacksonExample {
private List<Foo> foos;
}