映射对象值占多个String

Mapping object values accounting for multiple Strings

我收到来自外部休息电话的以下 json。

{
    // other keys coming in too, but already mapped
    "someData": {
        "someContent": {
        "item1": "",
        "otherItem25": "",
        "anotherData34": ""
        }
    }
}

我想将它映射到一个对象。

我可以执行以下有效的操作。

解决方案 1

private Map<String, Map<String, String>> someData;

但希望将其映射到命名对象。

喜欢以下也有效。

解决方案 2

class Root {
    private someData someData;
}

class SomeData {
    private SomeContent someContent;
}

class SomeContent {
    @JsonProperty("item1")
    private String one;

    @JsonProperty("otherItem25")
    private String two;

    @JsonProperty("anotherData34")
    private String three;
}

问题在于我单独命名字符串的最后一点。我不想那样做,因为这是为了成长 很快我就可以带着大约 50 根琴弦着陆了。我不想创建 50 个字符串。

除了上述2种解决方案,有没有更好的方法将这个json映射到一个对象?

像这样的东西本来是理想的,但行不通,因为在 json.

中没有任何东西可以识别为 nnerData
class SomeContent {
    private Map<String, String> innerData;
}

请指教

P.S: 我无法修改 json

看起来“理想情况”可以通过 @JsonCreator 注释实现,并将带有“innerData”的映射传递给构造函数。

class TestJson {

    @Test
    void test() throws Exception {

        var json = "{" +
                   "    \"someData\": {" +
                   "        \"someContent\": {" +
                   "            \"item1\": \"hello\"," +
                   "            \"otherItem25\": \"245hb24bt\"," +
                   "            \"anotherData34\": \"b42tb245\"" +
                   "}}}";

        var value = new ObjectMapper().readValue(json, Root.class);

        assertThat(value.someData.someContent.innerData.get("item1"))
            .isEqualTo("hello");
    }


    // here we use "public" just to make the code shorter
    // and let Jackson bind properties to the public fields
   
    static class Root {

       public SomeData someData;
    }

    static class SomeData {

       public SomeContent someContent;
    }

    static class SomeContent {

       public final Map<String, Object> innerData;

       @JsonCreator
       public SomeContent(Map<String, Object> anyName) {
           this.innerData = Map.copyOf(anyName);
           // notice that the map "anyName" is mutable
       }
    }
}

请仔细检查这里是否没有过度设计,这正是解决方案所需要的。可能,只需为“someContent”字段输入 Map 就足够了(并且在这种情况下还考虑处理地图可变性)。

class SomeData {
    Map<String, String> someContent;
}

如果我没看错问题,您似乎想要将对象的 大部分 映射为 Java beans,但想要 someContent 映射为 Map。假设是这种情况,您可以照常映射各种非 bean 属性,然后将 someContent 映射为内部 SomeData 类型上的 Map<String, String>

class Root {
    private SomeData someData;
}

class SomeData {
    private Map<String, String> someContent;
}
如果您的 json 是动态的并且会经常更改,那么

map 将是我认为的最佳选择。如果您只关心可能添加到 response 的任何随机事物的某些属性,那么只需将您需要的属性映射到 POJO 并使用 @JsonIgnoreProperty(ignore=unknown) 注释来忽略响应中出现的其他事物,您甚至有兴趣。