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());
}