【问题标题】:Can Jackson accept both wrapped and unwrapped Json when using JsonUnwrapped使用 JsonUnwrapped 时,Jackson 可以同时接受已包装和未包装的 Json
【发布时间】:2021-08-18 18:54:45
【问题描述】:

我有这样的课:

...
@JsonUnwrapped
private DataObject dataObject;
...

数据对象是

@Getter
public class DataObject {
    private String nested1;
    private String nested2;
}

显然,如果我的 Json 输入是,这将起作用

{
   "nested1" : "nestedValue1", 
   "nested2" : "nestedValue2"
}

有没有办法让它灵活地接受两个版本? 但是如果我想让它也能接受呢

{
   "dataObject: {
      "nested1" : "nestedValue1", 
      "nested2" : "nestedValue2"
   }
}

【问题讨论】:

    标签: json jackson


    【解决方案1】:

    从下面的your previous question 获取TestContract 类的代码:

    public class TestContract {
        private String field1;
    
        @JsonUnwrapped
        private DataObject dataObject;
    }
    

    解决问题的一种方法是为您的 TestContract 类编写一个自定义反序列化器,该类将使用以下 lombok 注释和 @JsonDeserialize 注释:

    @Getter
    @Setter
    @ToString
    @NoArgsConstructor
    @JsonDeserialize(using = TestContractDeserializer.class)
    public class TestContract {
        private String field1;
    
        @JsonUnwrapped
        private DataObject dataObject;
    }
    

    自定义反序列化程序将检查 field1 属性,然后检查 nested1nested2 两个属性是否嵌套在 dataObject 属性内,涵盖您提供的两种情况:

    public class TestContractDeserializer extends JsonDeserializer<TestContract> {
    
        @Override
        public TestContract deserialize(JsonParser jp, DeserializationContext dc) throws IOException, JsonProcessingException {
            JsonNode node = jp.getCodec().readTree(jp);
            //read the field1 property
            String field1 = node.get("field1").asText();
            JsonNode dataObjectNode = node.get("dataObject");
            //check if properties are nested or not
            if (dataObjectNode != null) {
                node = dataObjectNode;
            }
            String nested1 = node.get("nested1").asText();
            String nested2 = node.get("nested2").asText();
            DataObject dataObject = new DataObject();
            dataObject.setNested1(nested1);
            dataObject.setNested2(nested2);
            TestContract testContract = new TestContract();
            testContract.setDataObject(dataObject);
            testContract.setField1(field1);
            return testContract;
        }
    }
    

    【讨论】:

    • 我不想为 Contract 类自定义反序列化器,因为 DataObject 类可能出现在多个地方,我希望它的使用更加自动化
    • @PeterKronenberg 然后你可以访问存储父母的树,看看孩子是否像你要找的那样。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-19
    • 1970-01-01
    • 2019-09-06
    • 2017-05-24
    • 1970-01-01
    相关资源
    最近更新 更多