创建
类的首选方法是什么最好是,我希望这样的工作能够发挥作用:
@Data(onConstructor = @__(@JsonCreator))
然后将所有字段设为private final
。但是,这甚至没有编译(我不知道为什么)。使用
@AllArgsConstructor(onConstructor = @__(@JsonCreator))
将编译但仅产生
InvalidDefinitionException: No serializer found for class
答案 0 :(得分:16)
您可以使用Lombok的@Builder
注释为您的不可变POJO类生成构建器。
但是让杰克逊的反序列化使得Lombok生成的构建器可用是有点棘手的。
@JsonDeserialize(builder = ...)
注释您的POJO课程
告诉Jackson哪个是建筑师类使用。@JsonPOJOBuilder(withPrefix = "")
注释构建器类
告诉杰克逊其设置方法不以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);
}
}
答案 1 :(得分:12)
另一种选择:
是要添加 ConstructorProperties :
lombok.config
文件in an appropriate location:
lombok.anyConstructor.addConstructorProperties = true
@Value
注释以使其不可变然后,Jackson的序列化和反序列化将按预期进行。
答案 2 :(得分:3)
尝试为您的pojo使用以下注释集:
@Value
@NoArgsConstructor(force = true, access = AccessLevel.PRIVATE)
@AllArgsConstructor
答案 3 :(得分:3)
截至2020年10月15日龙目岛(v1.18.16),您应该只能够使用@Jacksonized
批注。
@Jacksonized @Builder @JsonIgnoreProperties(ignoreUnknown = true) public class JacksonExample { private List<Foo> foos; }
如链接文档中所述,此注释:
@JsonIgnoreProperties
),并且builder().withField(field)
和builder.field(field)
上使用的Jackson前缀与Lombok中配置的前缀对齐。答案 4 :(得分:1)
另一种不太冗长的选择:
@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;
}
答案 5 :(得分:1)
我已经用这种方式解决了它:
@Value
@Builder(setterPrefix = "with")
@JsonDeserialize(builder = Clazz.ClazzBuilder.class)
public class Clazz {
private String field;
}
在这种情况下,您必须使用withField(...)
之类的构建器方法,这是杰克逊使用的默认行为。
答案 6 :(得分:0)
通过引用answer by Joseph K. Strauss,我提出了以下解决方案。
对我有用的简单的龙目岛注释看起来像这样。以下注释为您提供了带有生成器的不变类,可以由Jackson进行序列化和反序列化。
@Data
@Setter(AccessLevel.NONE)
@Builder(toBuilder = true)
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class Clazz {
private String field;
}
我更喜欢这种解决方案,因为它不需要额外的Jackson specific annotations和不需要的lombok specific files
答案 7 :(得分:0)
托马斯·弗里奇(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>
答案 8 :(得分:0)
为Jackson配置不可变类的最简单方法是使用lombok注释:@Value
和@Jacksonized
:
@Jacksonized
@Builder
@Value
class Foo {
}