现在我正在与 Jackson 合作,我对此有一些疑问。
首先。我有两个服务,第一个是数据收集和发送服务,第二个是接收这些数据,例如,将其记录到一个文件中。
所以,第一个服务的类层次结构如下:
+----ConcreteC
|
Base ----+----ConcreteA
|
+----ConcreteB
第二个服务的类层次结构如下:
ConcreteAAdapter extends ConcreteA implements Adapter {}
ConcreteBAdapter extends ConcreteB implements Adapter {}
ConcreteCAdapter extends ConcreteC implements Adapter {}
第一个服务对ConcreteXAdapter
一无所知。
我在第一个服务上发送数据的方式:
Collection<Base> data = new LinkedBlockingQueue<Base>()
JacksonUtils utils = new JacksonUtils();
data.add(new ConcreteA());
data.add(new ConcreteB());
data.add(new ConcreteC());
...
send(utils.marshall(data));
...
public class JacksonUtils {
public byte[] marshall(Collection<Base> data) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream() {
@Override
public byte[] toByteArray() {
return buf;
}
};
getObjectMapper().writeValue(out, data);
return out.toByteArray();
}
protected ObjectMapper getObjectMapper() {
return new ObjectMapper();
}
public Object unmarshall(byte[] json) throws IOException {
return getObjectMapper().readValue(json, Object.class);
}
public <T> T unmarshall(InputStream source, TypeReference<T> typeReference) throws IOException {
return getObjectMapper().readValue(source, typeReference);
}
public <T> T unmarshall(byte[] json, TypeReference<T> typeReference) throws IOException {
return getObjectMapper().readValue(json, typeReference);
}
}
所以,我想将 json 反序列化为 ConcreteXAdapter
的集合,而不是 ConcreteX
的集合(ConcreteA -> ConcreteAAdapter, ConcreteB -> ConcreteBAdapter, ConcreteC -> 具体CAdapter
)。在我描述的情况下,我想得到:
Collection [ConcreteAAdapter, ConcreteBAdapter, ConcreteCAdapter]
我该怎么做?
最佳答案
为此,您需要在 JSON 中传递附加信息:
@JsonTypeInfo(use=JsonTypeInfo.Id.NAME,
include=JsonTypeInfo.As.PROPERTY, property="@type")
class Base {
...
}
然后在序列化时会添加@type 字段:
objectMapper.registerSubtypes(
new NamedType(ConcreteAAdapter.class, "ConcreteA"),
new NamedType(ConcreteBAdapter.class, "ConcreteB"),
new NamedType(ConcreteCAdapter.class, "ConcreteC")
);
// note, that for lists you need to pass TypeReference explicitly
objectMapper.writerWithType(new TypeReference<List<Base>>() {})
.writeValueAsString(someList);
{
"@type" : "ConcreteA",
...
}
在反序列化时它将是:
objectMapper.registerSubtypes(
new NamedType(ConcreteA.class, "ConcreteA"),
new NamedType(ConcreteB.class, "ConcreteB"),
new NamedType(ConcreteC.class, "ConcreteC")
);
objectMapper.readValue(....)
关于java - 使用 Jackson 将 Json 反序列化为其他类层次结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10329706/