将超类json反序列化为子类对象
我的软件主要围绕rfid设备运行.所有这些设备都具有(大部分)相同的配置选项,例如天线应以何种功率设置进行传输.但是,每个阅读器随附的API在设置天线功率方面有所不同.阅读器的配置在中央服务器上完成,并保存为json字符串.我正在尝试提出一种方法,使其具有一个通用的json字符串来配置天线功率(例如),而不必为每个API对其进行自定义.这就是我要实现的目标.
My software revolves heavily around rfid devices. All of these devices have have (mostly) the same configuration options such as what power setting the antennas should transmit at. However the APIs supplied with each reader differ in the way the antenna power is set. Configuration of the readers is done on a central server and saved as a json string. I am trying to come up a way to have a common json string to configure the antenna power (for example) without it having to be customised for each API. Here's what I'm trying to achieve.
用于设置天线功率的json字符串类似于:
The json string for setting antenna power would be something like:
{"power":30}
我用于配置电源的超类:
My super class for configuring power:
public abstract class SetPower<T> {
protected int power;
public SetPower(int power) {
this.power = power;
}
public abstract void configure(T rfidReader);
}
用于配置CompanyX读取器电源的子类:
Subclass for configuring power from CompanyX's reader:
public class CompanyXSetPower extends SetPower<CompanyXReader> {
@JsonCreator
public CompanyXSetPower(@JsonProperty("power") int power) {
super(power);
}
@Override
public void configure(CompanyXReader reader) {
reader.setPower((byte) power);
}
}
用于配置CompanyY读取器电源的子类:
Subclass for configuring power from CompanyY's reader:
public class CompanyYSetPower extends SetPower<CompanyYReader> {
@JsonCreator
public CompanyYSetPower(@JsonProperty("power") int power) {
super(power);
}
@Override
public void configure(CompanyYReader reader) {
reader.setOutputPower(power);
}
}
什么是将通用json反序列化为特定子类而不用向json字符串指定特定类详细信息的最佳"方法是什么.我可以在json字符串中包含超类详细信息,因为需要某种方法来标识json数据的对象类型.
What's the 'best' way to deserialize generic json into a specific subclass without having to specific class details to the json string. I am ok with including the superclass details to the json string as there needs to be some way of identifying what object type the json data is for.
您想要的就是将JSON反序列化为多态类型. (例如,请参见此问题类似问题).
What you want is called deserializing JSON into polymorphic types. (see for example this question for a similar problem).
您将需要在JSON内容中添加一个额外的type属性,
这样例如{"type":"x","power":30}
被反序列化
放入CompanyXSetPower
对象,
并且{"type":"y","power":30}
被反序列化
放入CompanyYSetPower
对象.
You will need to add an additional type attribute to your JSON content,
so that for example {"type":"x","power":30}
gets deserialized
into an CompanyXSetPower
object,
and {"type":"y","power":30}
gets deserialized
into an CompanyYSetPower
object.
为此,您需要使用以下方法增强抽象基类SetPower
:
@JsonTypeInfo
和 @JsonSubTypes
注释,这样杰克逊就会
了解有关JSON与您的各种Java类之间的映射的足够信息.
For this to work you need to enhance your abstract base class SetPower
with
@JsonTypeInfo
and @JsonSubTypes
annotations, so that Jackson will
have enough information about the mapping between JSON and your various Java classes.
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY, property = "type")
@JsonSubTypes({
@JsonSubTypes.Type(value = CompanyXSetPower.class, name = "x"),
@JsonSubTypes.Type(value = CompanyYSetPower.class, name = "y")
})
public abstract class SetPower<T> {
protected int power;
public SetPower(int power) {
this.power = power;
}
public abstract void configure(T rfidReader);
}
反序列化可以简单地通过以下方式完成:
The deserialization then can be simply done by:
ObjectMapper objectMapper = new ObjectMapper();
SetPower<?> setPower = objectMapper.readValue(url, SetPower.class);