如何用Jackson反序列化派生类?自动生成类无注解场景
解决方案:在无注解和类型信息的情况下反序列化子类实例
当然可以解决这个问题!因为你无法修改自动生成的类添加@JsonSubType等注解,也没法在输入的序列化内容里加入类型标识,我们可以通过Jackson的自定义反序列化器或者字段推断逻辑来处理,具体分两种场景说明:
场景1:所有ClauseType实例都应反序列化为DataMonitoringClauseType
如果你的输入中clauses列表里的元素全部是DataMonitoringClauseType的序列化结果,那可以直接强制将ClauseType类型的反序列化指向DataMonitoringClauseType:
步骤1:自定义反序列化器
创建一个针对ClauseType的反序列化器,直接把JSON解析为DataMonitoringClauseType实例:
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.deser.std.StdDeserializer; import java.io.IOException; public class ClauseTypeDeserializer extends StdDeserializer<ClauseType> { public ClauseTypeDeserializer() { super(ClauseType.class); } @Override public ClauseType deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { // 直接将JSON解析为DataMonitoringClauseType return p.readValueAs(DataMonitoringClauseType.class); } }
步骤2:注册反序列化器到ObjectMapper
把自定义的反序列化器注册到你的ObjectMapper实例中:
ObjectMapper mapper = new ObjectMapper(); SimpleModule customModule = new SimpleModule(); customModule.addDeserializer(ClauseType.class, new ClauseTypeDeserializer()); mapper.registerModule(customModule); // 现在反序列化RootClass时,clauses里的元素会是DataMonitoringClauseType实例 RootClass root = mapper.readValue(jsonInput, RootClass.class);
场景2:clauses列表中有多种ClauseType子类(需字段推断)
如果列表里可能存在不同的ClauseType子类,你可以通过JSON中的特定字段来推断具体类型(比如某个字段的存在或特定值),修改反序列化器的逻辑即可:
@Override public ClauseType deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { JsonNode node = p.getCodec().readTree(p); // 假设DataMonitoringClauseType对应的JSON有"monitoringConfig"字段 if (node.has("monitoringConfig")) { return p.getCodec().treeToValue(node, DataMonitoringClauseType.class); } // 其他子类的判断逻辑... else { // 默认返回ClauseType实例 return p.getCodec().treeToValue(node, ClauseType.class); } }
为什么registerSubtypes没用?
你之前尝试的mapper.registerSubtypes(DataMonitoringClauseType.class)之所以无效,是因为Jackson的registerSubtypes需要配合@JsonTypeInfo注解使用——这个注解告诉Jackson如何识别不同的子类(比如通过某个字段、类型名称等)。由于你的自动生成类没有添加这个注解,Jackson无法得知应该如何将JSON映射到对应的子类,所以单独注册子类是不起作用的。
内容的提问来源于stack exchange,提问作者suat
相关产品推荐
相关产品推荐

