Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/317.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用Jackson反序列化要映射的JSON数组_Java_Jackson - Fatal编程技术网

Java 使用Jackson反序列化要映射的JSON数组

Java 使用Jackson反序列化要映射的JSON数组,java,jackson,Java,Jackson,我的JSON结构如下: { "id" : "123", "name" : [ { "stuff" : [ { "id" : "234", "name" : "Bob" }, { "id" : "345", "name" : "Sally" } ] } ] } 我希望映射到以下数据结构: MyInterface1 @Value.Immutable @JsonSerialize(as = ImmutableMyIn

我的JSON结构如下:

{
  "id" : "123",
  "name" : [ {
    "stuff" : [ {
      "id" : "234",
      "name" : "Bob"
    }, {
      "id" : "345",
      "name" : "Sally"
    } ]
  } ]
}
我希望映射到以下数据结构:

MyInterface1

@Value.Immutable
@JsonSerialize(as = ImmutableMyInterface1.class)
@JsonDeserialize(as = ImmutableMyInterface1.class)
public interface MyInterface1 {
    String id();
    @JsonDeserialize(using = MyInterface1Deserializer.class)
    List<MyInterface2> name();
}
我正在使用一个带有
readValue(stringWithJson,MyInterface1.class)
的ObjectMapper将这个JSON映射到MyInterface1,它应该继续映射到MyInterface3。当我在MyInterface2中使用列表时,此设置正在运行,即
List name()

但是,我希望它是一个映射而不是一个列表,理想情况下是以内部JSON中的“id”作为键。这将允许我使用以下语法获取值:
MyInterface1.get(0.MyInterface2.get(“id1”).name()

问题是,在尝试创建自定义StuffDeserializer.class时,我遇到了以下错误:
无法反序列化com.foo.ImmutableMyInterface2$Json的实例,该实例不在START\u数组令牌中

尝试执行以下操作时:

public Map<String, MyInterface3> deserialize(JsonParser jsonParser, DeserializationContext ctxt)
        throws IOException {

    MyInterface2 foo = Unmarshaller.OBJECT_MAPPER.readValue(jsonParser, MyInterface2.class); // error here
    ...
公共映射反序列化(JsonParser JsonParser,反序列化上下文ctxt) 抛出IOException{ MyInterface2 foo=Unmarshaller.OBJECT_MAPPER.readValue(jsonParser,MyInterface2.class);//此处出错 ...

我认为这是因为Jackson希望“stuff”是一个列表,因为JSON数组。将此JSON反序列化为使用内部JSON值作为键的映射的最佳方法是什么?

我将创建一个自定义的
JsonDeserializer
以将
id
name
映射到映射中:

public class StringHashMapValueDeserializer extends JsonDeserializer<HashMap<String, String>>{

    @Override
    public HashMap<String, String> deserialize(JsonParser parser, DeserializationContext ctxt)
            throws IOException, JsonProcessingException {
        HashMap<String, String> ret = new HashMap<String, String>();

        ObjectCodec codec = parser.getCodec();
        TreeNode node = codec.readTree(parser);

        if (node.isArray()){
            for (JsonNode n : (ArrayNode)node){
                JsonNode id = n.get("id");
                if (id != null){
                    JsonNode name = n.get("name");
                    ret.put(id.asText(), name.asText());
                }
            }
        }
        return ret;
    }
}
外部类型:

@Getter
@Setter
public class OuterType {

    String id;
    List<Name> name;

    @Override
    public String toString() {
        return "OuterType [id=" + id + ", stuff=" + name + "]";
    }
}
控制台输出:

OuterType [id=123, stuff=[Name [stuff={234=Bob, 345=Sally}]]]
Bob
希望能有帮助

@Getter
@Setter
public class Name {

    @JsonDeserialize(using = StringHashMapValueDeserializer.class)
    Map<String, String> stuff;

    @Override
    public String toString() {
        return "Name [stuff=" + stuff + "]";
    }
}
@Getter
@Setter
public class OuterType {

    String id;
    List<Name> name;

    @Override
    public String toString() {
        return "OuterType [id=" + id + ", stuff=" + name + "]";
    }
}
ObjectMapper mapper = new ObjectMapper();

OuterType response;
response = mapper.readValue(json, OuterType.class);

System.out.println(response);
System.out.println(response.getName().get(0).getStuff().get("234"));
OuterType [id=123, stuff=[Name [stuff={234=Bob, 345=Sally}]]]
Bob