Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/387.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根据对象属性反序列化到POJO_Java_Json_Jaxb_Jackson - Fatal编程技术网

Java Jackson根据对象属性反序列化到POJO

Java Jackson根据对象属性反序列化到POJO,java,json,jaxb,jackson,Java,Json,Jaxb,Jackson,可以根据JSON的内容使用Jackson将JSON反序列化为两种类型之一吗 例如,我有以下Java(技术上是Groovy,但这并不重要)接口和类: interface Id { Thing toThing() } class NaturalId implements Id { final String packageId final String thingId Thing toThing() { new PackageIdentifie

可以根据JSON的内容使用Jackson将JSON反序列化为两种类型之一吗

例如,我有以下Java(技术上是Groovy,但这并不重要)接口和类:

interface Id {
    Thing toThing() 
}

class NaturalId implements Id {

    final String packageId

    final String thingId

    Thing toThing() {
        new PackageIdentifiedThing(packageId, thingId)
    }         
}

class AlternateId implements Id {

    final String key

    Thing toThing() {
        new AlternatelyIdentifiedThing(key)
    }
}
我将收到的JSON将如下所示:

这个JSON应该映射到naturaid
{“packageId”:“SomePackage”,“thingId”:“SomeEntity”}

这个JSON应该映射到AlternateId
{“key”:“SomeUniqueKey”}


有人知道我如何在不包含类型id的情况下用Jackson 2.x实现这一点吗

只有这两个类实现了
Id
?如果是这样,您可以编写一个
IdDeserializer
类,并将
@JsonDeserialize(using=IdDeserializer.class)
放在
Id
接口上,反序列化器将查看JSON并确定反序列化到哪个对象

编辑:JsonParser正在进行流式处理,因此它应该如下所示:

public Id deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException {
    ObjectNode node = jp.readValueAsTree();
    Class<? extends Id> concreteType = determineConcreteType(node); //Implement 
    return jp.getCodec().treeToValue(node, concreteType);
}
public Id反序列化(JsonParser jp,反序列化上下文ctxt)引发IOException{
ObjectNode=jp.readValueAsTree();

类使用@JsonIgnore注释您的方法

@JsonIgnore
Thing toThing() {
    new PackageIdentifiedThing(packageId, thingId)
}  

使用Jackson2,您可以使用泛型轻松地马歇尔到不同的类:

private <T> T json2Object(String jsonString, String type, Class<T> clazz) {
    JsonNode jsonObjectNode = getChildNode(jsonString, type);       
    T typeObject = null;
    try {
        typeObject = jacksonMapper.treeToValue(jsonObjectNode, clazz);
    } catch (JsonProcessingException jsonProcessingException) {
        LOGGER.severe(jsonProcessingException);
    }
    return typeObject;
}
private T json2Object(字符串jsonString,字符串类型,类clazz){
JsonNode jsonObjectNode=getChildNode(jsonString,类型);
T typeObject=null;
试一试{
typeObject=jacksonMapper.treeToValue(jsonObjectNode,clazz);
}捕获(JsonProcessingException JsonProcessingException){
LOGGER.严重(jsonProcessingException);
}
返回类型对象;
}

目前,只有这两种。在不久的将来可能会有第三种,但我预计不会出现Id类型爆炸。我将研究自定义反序列化方法,因为它可能是最有效的方法。我建议您的反序列化程序应该只确定要反序列化的
Id
的哪个实现到,然后委托给Jackson反序列化为该具体类型。这将使具体类型上的任何Jackson注释仍然受到尊重。(确保在具体类型上放置
@JsonDeserialize(使用=None.class)
,以避免无限的反序列化循环)HiJon,这是一个好主意,但我似乎遇到了这样一个问题;当我调用mapper.readValue(jsonParser,ConcreteType)时,我得到了以下错误:“由于输入结束,没有要映射的内容”其中,jsonParser是传递到反序列化方法中的类型,ConcreteType是我确定正确的类型。有什么想法吗?我感觉它与API的流性质有关。是的,jsonParser是流式的,您需要保留对读取对象的引用,并在读取对象后将其转换为具体类型已确定,我已为此添加了一个代码示例。明白了!谢谢。我将切换到已接受的答案。