自定义JsonDeserializer在resteasy中反序列化抽象类的子类型

时间:2015-11-05 13:11:34

标签: java json jackson wildfly

我有一个类:

public abstract class JsonMotivation {

    protected int motivationid;

    ... getters and setters

    public abstract String getMotivationType();
        public void setMotivationType(String motivationType) {
    }
} 

此motivType数据字段将保留参考

然后我有一些实现类,如:

@XmlRootElement
public class JsonAntibioticMotivation extends JsonMotivation {
    protected long smhid;
    protected int userid;

    @Override
    public String getMotivationType() {
        return "AB";
    }

    ... getters and setters
}

最后,我还有一些扩展JsonAntibioticMotivation类的类,例如

@XmlRootElement
public class JsonSwitchAntibioticMotivation extends JsonAntibioticMotivation {
    @Override
    public String getMotivationType() {
        return "AB-S";
    }
    ... some additional dataparameters
}

其中一个名为JsonMedicationhistory的类引用了抽象类JsonMotivation。在反序列化时,我得到一个错误说"无法构造be.uzgent.cosara.model.json.JsonMotivation的实例,问题:抽象类型要么需要映射到具体类型,要么有自定义反序列化器,要么用其他实例化类型信息"

杰克逊不知道用于反序列化的具体类是合乎逻辑的。我能以某种方式将motivationType映射到具体的类吗?我尝试用@JsonDeserialize(using=JsonMotivationDeserializer.class)编写自定义反序列化器和带注释的JsonMotivation

public class JsonMotivationDeserializer extends  JsonDeserializer<JsonMotivation> {

    @Override
    public JsonMotivation deserialize(JsonParser jp,
        DeserializationContext ctxt) throws IOException,
        JsonProcessingException {
        ObjectMapper mapper= new ObjectMapper();
        JsonNode node=jp.getCodec().readTree(jp);
        JsonNode motivationTypeNode=node.get("motivationType");
        if(motivationTypeNode!=null){
            String motivationType=motivationTypeNode.textValue();
            switch(motivationType){
                case "AB": return mapper.readValue(jp, JsonAntibioticMotivation.class);
                case "AB-N": return mapper.readValue(jp, JsonNewAntibioticMotivation.class);
                case "AB-S": return mapper.readValue(jp, JsonSwitchAntibioticMotivation.class);
                case "AB-E": return mapper.readValue(jp, JsonExtendAntibioticMotivation.class);
            }
        }
        return null;
    }
}

然而,这似乎并没有解决问题。 ObjectMapper似乎不知道原始映射。有没有办法在知道具体类后将其余的进程委托给原始的反序列化过程?

1 个答案:

答案 0 :(得分:1)

似乎我只需要用

来激活我的JsonMotivation类
@JsonTypeInfo(use=JsonTypeInfo.Id.CLASS, include=JsonTypeInfo.As.PROPERTY, property="@class")

然后可以删除自定义反序列化器。