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

Java 在Jackson中反序列化JSON,其中key是一个值,java,json,jackson,json-deserialization,Java,Json,Jackson,Json Deserialization,我有一个表示name(和其他字段)的类,我刚刚简化了这个问题。但是每个元素都是用人的id键的 我尝试过几件事,包括: { { "1234": { "name": "bob" } }, { "5678": { "name": "dan" } } } 关于正确解析这样的json字符串的最佳方法有什么想法吗?试试这个 java.lang.ClassCastException: java.util.

我有一个表示name(和其他字段)的类,我刚刚简化了这个问题。但是每个元素都是用人的id键的

我尝试过几件事,包括:

{
  {
      "1234": {
          "name": "bob"
      }
  },
  {
      "5678": {
          "name": "dan"
      }
  }
}
关于正确解析这样的json字符串的最佳方法有什么想法吗?

试试这个

java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to NameId
Iterator iterator1=outerObject.keys();
while(iterator1.hasNext())
{
JsonObject innerObject=outerObject.getJsonObject(iterator1.next());
迭代器迭代器2=innerObject.keys();
while(iterator2.hasNext()){
String name=innerObject.getString(iterator2.next());
}
} 

您的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());
}
} 
你可以建立这样的模型:

{
    "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 Map=newObjectMapper().readValue(json,
TypeFactory.defaultInstance()
.constructMapType(Map.class、Integer.class、Person.class));

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

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

[
    {
        "1234" : {
            "name" : "dan"
        }
    },
    {
        "5678" : {
            "name" : "mike"
        }
    }
]
publicstaticvoidmain(String…args)引发异常{
字符串testJson=“[{\'1234\':{\'name\':\'dan\'},{\'5678\':{\'name\':\'mike\'}]”;
ObjectMapper mapper=新的ObjectMapper();
SimpleModule=新的SimpleModule();
addDeserializer(NameId.class,新的MyDeserializer());
映射器注册表模块(模块);
ArrayList map=mapper.readValue(testJson.getBytes(),new TypeReference()){
});
for(NameId m:map){
系统输出打印项次(m.id);
System.out.println(m.name.name);
System.out.println(“---”);
}
}
@JsonDeserialize(contentUsing=MyDeserializer.class)
静态类NameId{
字符串id;
姓名;
//二传手
}
静态类名{
字符串名;
//接二连三
}
静态类MyDeserializer扩展JsonDeserializer{
@凌驾
public NameId反序列化(JsonParser,反序列化上下文ctxt)
抛出IOException、JsonProcessingException{
JsonNode node=p.getCodec().readTree(p);
Map.Entry nodeData=node.fields().next();
字符串id=nodeData.getKey();
字符串名称=nodeData.getValue().get(“name”).asText();
Name nameObj=新名称();
nameObj.name=名称;
NameId nameIdObj=新的NameId();
nameIdObj.name=nameObj;
nameidbj.id=id;
返回nameIdObj;
}
}

不需要自定义反序列化程序

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

其次。以下是两个单独的类文件:

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

以及非常简单的json解析器类

@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;
    }
}
公共类JsonParser{
/**
*@param args
*@抛出异常
*/
公共静态void main(字符串[]args)引发IOException{
String jsonString=新字符串(Files.readAllBytes(path.get(“test.json”));
ObjectMapper mapper=新的ObjectMapper();
Map nameIdList=mapper.readValue(jsonString,new TypeReference(){});
nameIdList.entrySet().forEach(NameIdentity->System.out.println(“名称id为:”+NameIdentity.getKey()+
名称为:“+nameIdentitry.getValue().getName().getName());
}
}

还有。这简直是一场骗局。你应该读一下。

你的JSON格式肯定不正确。不需要强制转换。我不明白你的意思。更新了json,我试着用[]和{}来解决这个问题。这不是一个好的解决方案。为什么要从jackson&fasterxml转换为简单的json来实现这样的解决方案?这比必要的代码多得多这比必要的代码复杂得多这真的很糟糕。你只需要一行代码!在这个解决方案中,我在.fields()上得到一个编译错误,表示“对于类型JsonNode,方法字段()未定义”。我将其更改为getFields,并得到一个运行时错误:java.util.NoTouchElementException您使用的依赖项是什么?这些依赖项看起来很旧。我使用了:编译组:'com.fasterxml.jackson.core',名称:'jackson core',版本:'2.9.4',编译组:'com.fasterxml.jackson.core',名称:'jackson databind',版本:'2.9.4',您能更新它们吗?在更新我的版本并添加方括号后,这个答案有效,谢谢!
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;
    }
}
{
    "1234": {
        "name": "bob"
    },
    "5678": {
        "name": "dan"
    }
}
@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;
    }
}
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()));

    }

}