杰克逊平 JSON class/record 一场
Flat JSON in Jackson for class/record with one field
我有一个只有一个字段的 Java 记录:
public record AggregateId(UUID id) {}
还有一个带有 AggregateId
字段的 class(为了便于阅读,删除了其他字段)
public class Aggregate {
public final AggregateId aggregateId;
@JsonCreator
public Aggregate(
@JsonProperty("aggregateId") AggregateId aggregateId
) {
this.aggregateId = aggregateId;
}
}
上面的实现序列化和反序列化 JSON 给定的例子:
ObjectMapper objectMapper = new ObjectMapper();
String content = """
{
"aggregateId": {
"id": "3f61aede-83dd-4049-a6ff-337887b6b807"
}
}
""";
Aggregate aggregate = objectMapper.readValue(content, Aggregate.class);
System.out.println(objectMapper.writeValueAsString(aggregate));
我如何更改 Jackson 配置以将 JSON 替换为:
{
"aggregateId": "3f61aede-83dd-4049-a6ff-337887b6b807"
}
不放弃 AggregateId
的单独 class 并通过字段访问,没有 getters?
我尝试了 @JsonUnwrapper
注释,但这导致抛出
Exception in thread "X" com.fasterxml.jackson.databind.exc.InvalidDefinitionException:
Invalid type definition for type `X`:
Cannot define Creator parameter as `@JsonUnwrapped`: combination not yet supported at [Source: (String)"{
"aggregateId": "3f61aede-83dd-4049-a6ff-337887b6b807"
}"
或
Exception in thread "X" com.fasterxml.jackson.databind.exc.InvalidDefinitionException:
Cannot define Creator property "aggregateId" as `@JsonUnwrapped`:
combination not yet supported at [Source: (String)"{
"aggregateId": "3f61aede-83dd-4049-a6ff-337887b6b807"
}"
杰克逊版本:2.13.1
dependencies {
compile "com.fasterxml.jackson.core:jackson-annotations:2.13.1"
compile "com.fasterxml.jackson.core:jackson-databind:2.13.1"
}
当然,可以使用自定义 serializer/deserializer,但我正在寻找更简单的解决方案,因为我有许多不同的 class 有类似问题。
目前还不支持@JsonUnwrapped
和@JsonCreator
的组合,所以我们可以这样生成解决方案:
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonUnwrapped;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import java.util.UUID;
public class AggregateTest {
static record AggregateId(@JsonProperty("aggregateId") UUID id) {}
static class Aggregate {
@JsonUnwrapped
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
public final AggregateId _aggregateId;
public final String otherField;
@JsonCreator
public Aggregate(@JsonProperty("aggregateId") UUID aggregateId,
@JsonProperty("otherField") String otherField) {
this._aggregateId = new AggregateId(aggregateId);
this.otherField = otherField;
}
}
public static void main(String[] args) throws JsonProcessingException {
String rawJson =
"{\"aggregateId\": \"1f61aede-83dd-4049-a6ff-337887b6b807\"," +
"\"otherField\": \"İsmail Y.\"}";
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
Aggregate aggregate = objectMapper
.readValue(rawJson, Aggregate.class);
System.out.println(objectMapper
.writeValueAsString(aggregate));
}
}
这里我们简单地去掉 @JsonUnwrapped
字段。
我们得到名称为 aggregateId
的 UUID
并创建一个 AggregateId
记录.
详细解释:
我有一个只有一个字段的 Java 记录:
public record AggregateId(UUID id) {}
还有一个带有 AggregateId
字段的 class(为了便于阅读,删除了其他字段)
public class Aggregate {
public final AggregateId aggregateId;
@JsonCreator
public Aggregate(
@JsonProperty("aggregateId") AggregateId aggregateId
) {
this.aggregateId = aggregateId;
}
}
上面的实现序列化和反序列化 JSON 给定的例子:
ObjectMapper objectMapper = new ObjectMapper();
String content = """
{
"aggregateId": {
"id": "3f61aede-83dd-4049-a6ff-337887b6b807"
}
}
""";
Aggregate aggregate = objectMapper.readValue(content, Aggregate.class);
System.out.println(objectMapper.writeValueAsString(aggregate));
我如何更改 Jackson 配置以将 JSON 替换为:
{
"aggregateId": "3f61aede-83dd-4049-a6ff-337887b6b807"
}
不放弃 AggregateId
的单独 class 并通过字段访问,没有 getters?
我尝试了 @JsonUnwrapper
注释,但这导致抛出
Exception in thread "X" com.fasterxml.jackson.databind.exc.InvalidDefinitionException:
Invalid type definition for type `X`:
Cannot define Creator parameter as `@JsonUnwrapped`: combination not yet supported at [Source: (String)"{
"aggregateId": "3f61aede-83dd-4049-a6ff-337887b6b807"
}"
或
Exception in thread "X" com.fasterxml.jackson.databind.exc.InvalidDefinitionException:
Cannot define Creator property "aggregateId" as `@JsonUnwrapped`:
combination not yet supported at [Source: (String)"{
"aggregateId": "3f61aede-83dd-4049-a6ff-337887b6b807"
}"
杰克逊版本:2.13.1
dependencies {
compile "com.fasterxml.jackson.core:jackson-annotations:2.13.1"
compile "com.fasterxml.jackson.core:jackson-databind:2.13.1"
}
当然,可以使用自定义 serializer/deserializer,但我正在寻找更简单的解决方案,因为我有许多不同的 class 有类似问题。
目前还不支持@JsonUnwrapped
和@JsonCreator
的组合,所以我们可以这样生成解决方案:
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonUnwrapped;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import java.util.UUID;
public class AggregateTest {
static record AggregateId(@JsonProperty("aggregateId") UUID id) {}
static class Aggregate {
@JsonUnwrapped
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
public final AggregateId _aggregateId;
public final String otherField;
@JsonCreator
public Aggregate(@JsonProperty("aggregateId") UUID aggregateId,
@JsonProperty("otherField") String otherField) {
this._aggregateId = new AggregateId(aggregateId);
this.otherField = otherField;
}
}
public static void main(String[] args) throws JsonProcessingException {
String rawJson =
"{\"aggregateId\": \"1f61aede-83dd-4049-a6ff-337887b6b807\"," +
"\"otherField\": \"İsmail Y.\"}";
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
Aggregate aggregate = objectMapper
.readValue(rawJson, Aggregate.class);
System.out.println(objectMapper
.writeValueAsString(aggregate));
}
}
这里我们简单地去掉 @JsonUnwrapped
字段。
我们得到名称为 aggregateId
的 UUID
并创建一个 AggregateId
记录.
详细解释: