Jackson 中的扁平 JSON,用于具有一个字段的类/记录/值对象

M. *_*dek 5 java jackson deserialization jackson-databind

我有一条只有一个字段的 Java 记录:

public record AggregateId(UUID id) {}
Run Code Online (Sandbox Code Playgroud)

以及一个带有该AggregateId字段的类(为了可读性而删除了其他字段)

public class Aggregate {

    public final AggregateId aggregateId;

    @JsonCreator
    public Aggregate(
            @JsonProperty("aggregateId") AggregateId aggregateId
    ) {
        this.aggregateId = aggregateId;
    }
}
Run Code Online (Sandbox Code Playgroud)

上面的实现使用给定的示例序列化和反序列化 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));
Run Code Online (Sandbox Code Playgroud)

我如何更改 Jackson 配置以替换 JSON:

{
    "aggregateId": "3f61aede-83dd-4049-a6ff-337887b6b807"
}
Run Code Online (Sandbox Code Playgroud)

不放弃一个单独的类AggregateId并通过字段进行访问,没有吸气剂?

我尝试了@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"
        }"
Run Code Online (Sandbox Code Playgroud)

或者

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"
        }"
Run Code Online (Sandbox Code Playgroud)

杰克逊版本:2.13.1

dependencies {
    compile "com.fasterxml.jackson.core:jackson-annotations:2.13.1"
    compile "com.fasterxml.jackson.core:jackson-databind:2.13.1"
}
Run Code Online (Sandbox Code Playgroud)

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

İsm*_* Y. 3

尚不支持@JsonUnwrapped和的组合@JsonCreator,因此我们可以生成如下解决方案:

\n
import com.fasterxml.jackson.annotation.JsonCreator;\nimport com.fasterxml.jackson.annotation.JsonProperty;\nimport com.fasterxml.jackson.annotation.JsonUnwrapped;\nimport com.fasterxml.jackson.core.JsonProcessingException;\nimport com.fasterxml.jackson.databind.ObjectMapper;\nimport com.fasterxml.jackson.databind.SerializationFeature;\n\nimport java.util.UUID;\n\npublic class AggregateTest {\n\n    static record AggregateId(@JsonProperty("aggregateId") UUID id) {}\n\n    static class Aggregate {\n\n        @JsonUnwrapped\n        @JsonProperty(access = JsonProperty.Access.READ_ONLY)\n        public final AggregateId _aggregateId;\n        public final String otherField;\n\n        @JsonCreator\n        public Aggregate(@JsonProperty("aggregateId") UUID aggregateId,\n                         @JsonProperty("otherField") String otherField) {\n            this._aggregateId = new AggregateId(aggregateId);\n            this.otherField = otherField;\n        }\n    }\n\n    public static void main(String[] args) throws JsonProcessingException {\n        String rawJson =\n            "{\\"aggregateId\\": \\"1f61aede-83dd-4049-a6ff-337887b6b807\\"," +\n                    "\\"otherField\\": \\"\xc4\xb0smail Y.\\"}";\n        ObjectMapper objectMapper = new ObjectMapper();\n        objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);\n        Aggregate aggregate = objectMapper\n                .readValue(rawJson, Aggregate.class);\n        System.out.println(objectMapper\n                .writeValueAsString(aggregate));\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

这里我们简单地摆脱这个@JsonUnwrapped领域。

\n

我们获取UUID名称aggregateId并创建一条AggregateId记录

\n

关于它的详细解释:

\n\n