Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/389.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反序列化_Java_Json_Rest_Jackson_Deserialization - Fatal编程技术网

Java 多类型上的Jackson反序列化

Java 多类型上的Jackson反序列化,java,json,rest,jackson,deserialization,Java,Json,Rest,Jackson,Deserialization,我有一个名为Instance的抽象类,然后是它的两个实现,UserInstance和HardwareInstance。我遇到的问题是,当我为一个@POST调用rest端点到数据库中时,理想情况下,我希望它像../rest/soexample/instance/create一样,将实例传递到rest端点。如果Instance不是一个以上的抽象实现,那就可以了,但是因为我有2个,所以我得到了一个Jackson.databind错误 问题:抽象类型需要映射到具体类型,具有自定义反序列化程序,或者使用其

我有一个名为
Instance
的抽象类,然后是它的两个实现,
UserInstance
HardwareInstance
。我遇到的问题是,当我为一个
@POST
调用rest端点到数据库中时,理想情况下,我希望它像
../rest/soexample/instance/create
一样,将实例传递到rest端点。如果
Instance
不是一个以上的抽象实现,那就可以了,但是因为我有2个,所以我得到了一个
Jackson.databind
错误

问题:抽象类型需要映射到具体类型,具有自定义反序列化程序,或者使用其他类型信息实例化

在查找解决方案后,我找到了一个答案,该答案表示我可以使用以下内容:

@JsonDeserialize(as=UserInstance.class)

但这似乎只有在抽象类有一个实现时才有用。假设我不能调用它两次,因为它无法决定它将是哪种类型的实例

所以我想知道处理这种情况的最好方法是什么?我应该创建不同的端点吗?比如:

../rest/soexample/userinstance/create
&
../rest/soexample/hardwareininstance/create


我不太确定,因为我是一个与休息相关的人,尽管我在积极努力学习。谢谢

以下是我在你同样的案例中所做的:

@JsonDeserialize(using = InstanceDeserializer.class)
public abstract class Instance {
    //.. methods
}

@JsonDeserialize(as = UserInstance.class)
public class UserInstance extends Instance {
    //.. methods
}

@JsonDeserialize(as = HardwareInstance.class)
public class HardwareInstance extends Instance {
    //.. methods
}

public class InstanceDeserializer extends JsonDeserializer<Instance> {
    @Override
    public Instance deserialize(JsonParser jp,  DeserializationContext ctxt) throws IOException, JsonProcessingException {
        ObjectMapper mapper = (ObjectMapper) jp.getCodec();
        ObjectNode root = (ObjectNode) mapper.readTree(jp);
        Class<? extends Instance> instanceClass = null;
        if(checkConditionsForUserInstance()) {
            instanceClass = UserInstance.class;
        } else { 
            instanceClass = HardwareInstance.class;
        }   
        if (instanceClass == null){
            return null;
        }
        return mapper.readValue(root, instanceClass );
    }
}
@JsonDeserialize(使用=InstanceDeserializer.class)
公共抽象类实例{
//…方法
}
@JsonDeserialize(as=UserInstance.class)
公共类UserInstance扩展实例{
//…方法
}
@JsonDeserialize(as=HardwareInstance.class)
公共类硬件实例扩展实例{
//…方法
}
公共类InstanceDeserializer扩展JsonDeserializer{
@凌驾
公共实例反序列化(JsonParser jp,DeserializationContext ctxt)抛出IOException,JsonProcessingException{
ObjectMapper映射器=(ObjectMapper)jp.getCodec();
ObjectNode root=(ObjectNode)mapper.readTree(jp);

ClassYou可以为该抽象类编写自定义反序列化程序,该类必须根据字段以编程方式解析JSON,并将主体解析为您心目中的任何具体类。感谢您的建议。我以前从未这样做过。我应该将自定义反序列化程序放置在何处?是否从末尾内部调用它
../rest/soexample/instance/create
?rest是一种非特定类型的应用程序,它不能告诉我您使用的是什么服务器/客户端技术。我发现一个与我想到的解决方案非常相似的问题:我通常会将反序列化器作为您正在使用的对象的公共静态内部类正在尝试反序列化。checkConditionsForUserInstance()中的逻辑应该是什么方法?我们是否在ctxt中获得此实例信息?不,这只是一个方法,您可以自己来区分要反序列化反Json的类。此时,您必须有某种机制来区分与Json关联的具体类。如果子类像您所说的那样不受您的控制,可能您应该添加一个xtra是Json的一个强制参数,它告诉您需要的具体类。您也可以检查
@JsonTypeInfo
注释,但我认为它不适合您的场景。最终,尽管非常复杂,但您可以使用反射扫描接口的所有实现类,并匹配与e Json,然后反序列化为该Json。我想不出其他任何东西了。非常感谢!!我确实通过使用@JsonTypeInfo(use=JsonTypeInfo.Id.CLASS,include=JsonTypeInfo.As.PROPERTY,PROPERTY=“type”)解决了这个问题在我的界面顶部。它在json中添加了一个类型字段,在保存时,反序列化它会使用该值。因此它正按照您的建议进行操作。最后一行不应该是
return mapper.convertValue(root,instanceClass);