在 Jackson 中反序列化 JSON,其中键是一个值

Deserialize JSON in Jackson where key is a value

{
  {
      "1234": {
          "name": "bob"
      }
  },
  {
      "5678": {
          "name": "dan"
      }
  }
}

我有一个 class 表示名称(和其他字段,我只是简单地解决了这个问题)。但是每个元素都以人的 id 为关键字。

我尝试了几种方法,包括:

class Name {
     String Name;
     //getter and setter
}
class NameId {
     String id;
     Name name;
     //getter and setters
}

//json is the string containing of the above json
ArrayList<NameId> map = objectMapper.readValue(json, ArrayList.class);
for (Object m : map) {
    LinkedHashMap<String, NameId> l = (LinkedHashMap)m;
            Map<String, NameId> value = (Map<String, NameId>) l;

            //System.out.println(l);
            //System.out.println(value);
            for (Object key : value.keySet()) {
                System.out.println("key: " + key);
                System.out.println("obj: " + value.get(key));

                NameId nameId = (NameId)value.get(key);

            }
}

我遇到的问题是它不允许强制转换为 NameId。我得到的错误是:

java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to NameId

关于正确解析这样的 json 字符串的最佳方法有什么想法吗?

试试这个

Iterator<String> iterator1 =outerObject.keys();
while(iterator1.hasNext())
{
JsonObject innerObject=outerObject.getJsonObject(iterator1.next());
Iterator<String> iterator2=innerObject.keys();
while(iterator2.hasNext()){
String name=innerObject.getString(iterator2.next());
}
} 

您的 json 无效。可能有点不同:

{
    "1234": {
        "name": "bob"
    },
    "5678": {
        "name": "dan"
    }
}

你可以这样建模:

class Person {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

不要尝试使用列表,而是使用地图:

Map<Integer, Person> map = new ObjectMapper().readValue(json,
    TypeFactory.defaultInstance()
            .constructMapType(Map.class, Integer.class, Person.class));

您的 json 格式不正确。您需要在它周围加上方括号,否则它不会被视为 json 数组。如果您的 json 看起来像(例如)

[
    {
        "1234" : {
            "name" : "dan"
        }
    },
    {
        "5678" : {
            "name" : "mike"
        }
    }
]

您可以为对象映射器编写自定义反序列化程序。请参阅下面的工作示例:

public static void main(String... args) throws Exception {
    String testJson = "[{ \"1234\" : { \"name\" : \"dan\" } },{ \"5678\" : { \"name\" : \"mike\" } }]";

    ObjectMapper mapper = new ObjectMapper();
    SimpleModule module = new SimpleModule();
    module.addDeserializer(NameId.class, new MyDeserializer());
    mapper.registerModule(module);
    ArrayList<NameId> map = mapper.readValue(testJson.getBytes(), new TypeReference<List<NameId>>() {
    });
    for (NameId m : map) {
        System.out.println(m.id);
        System.out.println(m.name.name);
        System.out.println("----");
    }
}


@JsonDeserialize(contentUsing = MyDeserializer.class)
static class NameId {
     String id;
     Name name;
     //getter and setters
    }

static class Name {
     String name;
     //getter and setter
}

static class MyDeserializer extends JsonDeserializer<NameId> {

    @Override
    public NameId deserialize(JsonParser p, DeserializationContext ctxt)
            throws IOException, JsonProcessingException {
        JsonNode node = p.getCodec().readTree(p);
        Map.Entry<String, JsonNode> nodeData = node.fields().next();
        String id = nodeData.getKey();
        String name = nodeData.getValue().get("name").asText();
        Name nameObj = new Name();
        nameObj.name = name;
        NameId nameIdObj = new NameId();
        nameIdObj.name = nameObj;
        nameIdObj.id = id;
        return nameIdObj;
    }
}

不需要自定义解串器。

首先,@klaimmore 建议的 json 文件(命名为 test.json):

{
    "1234": {
        "name": "bob"
    },
    "5678": {
        "name": "dan"
    }
}

其次。这是 2 个单独的 class 文件:

@JsonDeserialize
public class Name {
    String name;

    public Name(String name) {
        this.name = name;
    }
    /**
     * @return the name
     */
    public String getName() {
        return name;
    }

    /**
     * @param name the name to set
     */
    public void setName(String name) {
        this.name = name;
    }
}

@JsonDeserialize
public class NameId {
    Name name;
    String id;
    /**
     * @return the id
     */
    public String getId() {
        return id;
    }
    /**
     * @param id the id to set
     */
    public void setId(String id) {
        this.id = id;
    }
    /**
     * @return the name
     */
    public Name getName() {
        return name;
    }
    /**
     * @param name the name to set
     */
    public void setName(Name name) {
        this.name = name;
    }
}

和额外简单的 json 解析器 class.

public class JsonParser {

    /**
     * @param args
     * @throws IOException 
     */
    public static void main(String[] args) throws IOException {

        String jsonString = new String(Files.readAllBytes(Paths.get("test.json")));
        ObjectMapper mapper = new ObjectMapper();
        Map<String,NameId> nameIdList = mapper.readValue(jsonString, new TypeReference<Map<String,NameId>>(){});
        nameIdList.entrySet().forEach(nameIdEntry -> System.out.println("name id is: " + nameIdEntry.getKey() + 
                " and name is: " + nameIdEntry.getValue().getName().getName()));

    }

}

还有。这几乎是 的骗局。你应该读读这个。