Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/382.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.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_Json_Jackson_Deserialization - Fatal编程技术网

Java Jackson:如何使用速记属性值反序列化json

Java Jackson:如何使用速记属性值反序列化json,java,json,jackson,deserialization,Java,Json,Jackson,Deserialization,我正在努力找出如何使用Jackson将以下带有速记约定的JSON反序列化为javapojo [ { "id":1, "type": "simple" }, { "id":2, "type": { "kind": "simple" } }, { "id":3, "type": { "kind": "complex", "someOtherThing": "value" } } ] 此处的

我正在努力找出如何使用Jackson将以下带有速记约定的JSON反序列化为javapojo

[
  { 
    "id":1,
    "type": "simple"
  },
  { 
    "id":2,
    "type": { "kind": "simple" }
  },
  { 
    "id":3,
    "type": {
      "kind": "complex",
      "someOtherThing": "value"
    }
  }
]
此处的“type”属性可以是字符串或对象。如果它是一个字符串,那么它被认为是具有默认属性的同一对象的简单速记形式。即,上述示例中的1和2是等效的


据我所知,可以为整个“type”对象编写自定义反序列化程序。据我所知,在这种情况下,我必须手动反序列化整个“type”对象。但我真的希望只手动处理速记表单,并将正常处理委托给基于注释的映射器。这是可能的吗?

您可以简单地用一个参数定义一个构造函数,该参数将创建一个简单类型的对象。在您的情况下,
类型
类将有一个
字符串
构造函数。别忘了还包括一个noargs构造函数

public static void main(String [] args) throws JsonParseException, JsonMappingException, IOException {
    String str = "[ {\"id\":1,\"type\":\"simple\" }, {\"id\":2,\"type\": {\"kind\":\"simple\" } }, {\"id\":3,\"type\": {\"kind\":\"complex\",\"someOtherThing\":\"value\" } }]";
    ObjectMapper mapper = new ObjectMapper();
    MyObject[] objs = mapper.readValue(str.getBytes(), MyObject[].class);
    for(MyObject obj : objs) {
        System.out.println(obj.id + " " + obj.type.kind + " " + obj.type.someOtherThing);
    }
}

public static class MyObject {
    public String id;
    public Type type;
}

public static class Type {
    public String kind;
    public String someOtherThing;

    public Type() {
    }

    public Type(String kind) {
        this.kind = kind;
    }
}
打印出来

1 simple null
2 simple null
3 complex value

您可能需要为
类型
编写一个自定义
BeanDeserializer
子类。但是,您可以利用Jackson的其余部分来处理类型对象

最好的选择是
@JsonIgnore
对象中的type属性。然后,在自定义反序列化程序中,重写
handleIgnoredProperty()
。在此方法中,执行以下操作:

protected void handleIgnoredProperty(JsonParser jp, DeserializationContext ctxt, Object beanOrClass, String propName)
        throws IOException, JsonProcessingException {
  if ("type".equals(propName)) {
     if (jp.getCurrentToken() != JsonToken.START_OBJECT) {
       MyObjectDeserializer myObjectDeserializer = (MyObjectDeserializer) ctxt.findRootValueDeserializer(ctxt                   .getTypeFactory().constructType(MyObject.class));
       MyObject myObject = (MyObject) myObjectDeserializer.deserialize(jp, ctxt);
       // cast beanOrClass to your object and call object.setType(myObject)
     }
     else {
        // get a StringDeserializer and call object.setType(string)
     }
  }
  else {
    super.handleIgnoredProperty(jp, ctxt, beanOrClass, propName);
  }
}
您可能需要进行更多的处理,以便使用
jp.nextToken()
手动读取种类值,以访问
其他内容
,但我希望这足以让您开始