Jackson中带有一个字段的类/记录/值对象的平面JSON



我有一个Java记录,只有一个字段:

public record AggregateId(UUID id) {}

和一个具有AggregateId字段的类(为了可读性,删除了其他字段(

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的单独类和通过字段的访问,而不使用getter?

我尝试了@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"
}"

Jackson版本:2.13.1

dependencies {
compile "com.fasterxml.jackson.core:jackson-annotations:2.13.1"
compile "com.fasterxml.jackson.core:jackson-databind:2.13.1"
}

当然,使用自定义序列化程序/反序列化程序是可能的,但我正在寻找一个更简单的解决方案,因为我有许多不同的类都有类似的问题

还不支持@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字段。

我们获得名为aggregateIdUUID,并创建一个AggregateId记录

关于它的详细解释:

  • https://github.com/FasterXML/jackson-databind/issues/1467
  • https://github.com/FasterXML/jackson-databind/issues/1497

最新更新