Java 让Spring/Jackson智能地反序列化模型子类

Java 让Spring/Jackson智能地反序列化模型子类,java,json,spring,jackson,Java,Json,Spring,Jackson,给定这样的模型层次结构: // WARNING: This is pseudo-code for giving an example! public abstract class BaseVehicle { private String make; private String model; // Constructors, getters & setters down here } public class Motorcycle extends BaseVe

给定这样的模型层次结构:

// WARNING: This is pseudo-code for giving an example!
public abstract class BaseVehicle {
    private String make;
    private String model;

    // Constructors, getters & setters down here
}

public class Motorcycle extends BaseVehicle {
    private int numCylinders;

    // Constructors, getters & setters down here
}

public class Car extends BaseVehicle {
    // ...etc.
}
并给出以下有效载荷等级(将发送至弹簧控制器):

我想知道是否有可能将Spring控制器(使用Jackson进行JSON序列化)配置为只在它接收的
有效负载中预期
BaseVehicle
实例,而动态推断到底发送了哪个
BaseVehicle
子类:

@RequestMapping(value='/payload', method=RequestMethod.POST)
@ResponseStatus(value = HttpStatus.OK)
@ResponseBody MyAppResponse onPayload(@RequestBody Payload payload) {
    logger.info("Received a payload with a vehicle of type: " + payload.getVehicle().getClass().getName());
}
因此,如果我碰巧发送了一个
有效载荷
JSON,其中包含一个
摩托车
作为其
车辆
字段,那么当该
logger.info(…)
语句触发时,代码会看到
车辆
是一个
摩托车
(对于任何其他
基本车辆
子类也是如此)

这是否可能,如果可能,如何实现?

然而,我非常喜欢一个允许JSON保持原样的解决方案

正如我在上面的评论中提到的,您可以分析payload vehicle JSON对象树,以便进行一些分析,尝试检测payload元素类型

@JsonDeserialize(使用=BaseVehicleJsonDeserializer.class)
抽象类基本载体{
@JsonProperty
私人字符串制作;
@JsonProperty
私有字符串模型;
}
@JsonDeserialize(as=Car.class)
末级车
扩展基本车辆{
}
@JsonDeserialize(as=Motorcycle.class)
末级摩托车
扩展基本车辆{
@JsonProperty
私人国际货币基金组织;
}
这里的技巧是
@JsonDeserialize
注释。
BaseVehicleJsonDeserializer
可以按如下方式实现:

final类BaseVehicleJsonDeserializer
扩展JsonDeserializer{
@凌驾
公共BaseVehicle反序列化(最终JsonParser解析器,最终反序列化上下文)
抛出IOException{
final TreeNode TreeNode=parser.readValueAsTree();

最后一个类在son中没有其他信息,我对此表示怀疑。Jackson需要知道以某种方式创建哪种类型。没有具体信息或扩展,它不知道。谢谢@M.Deinum(+1)-如果在JSON中提供额外信息是这里唯一的解决方案,我会对该解决方案的外观感兴趣。但是我非常喜欢一个允许JSON保持原样的解决方案。再次感谢!@smeeb我认为这并不容易。通常是“抽象的”elements JSON文档提供了一个特殊的类型标记属性,允许JSON反序列化程序实例化元素权限。另一个选项是基于
BaseVehicle
子类具有不同的结构(唯一名称、字段类型等),因此您可以保持JSON的原样:具有JSON树(可能在内存中),可以分析JSON树,并“启发式地”实例化一个具体元素“推断”其类型。
@RequestMapping(value='/payload', method=RequestMethod.POST)
@ResponseStatus(value = HttpStatus.OK)
@ResponseBody MyAppResponse onPayload(@RequestBody Payload payload) {
    logger.info("Received a payload with a vehicle of type: " + payload.getVehicle().getClass().getName());
}