我有一组这样的抽象类:
abstract class A {
public abstract B getB() {return this.b;}
public abstract void setB(B b) {this.b = b;}
}
abstract class B {
public abstract C getC() {return this.c;}
public abstract void setC(C c) {this.c = c;}
}
abstract class C {
private String foo;
public String getFoo() {return this.foo;}
public void setFoo(String foo) {this.foo = foo;}
}
在运行时,我使用ByteBuddy为这些类创建代理。我可以轻松地将这些代理类的对象序列化为XML。但是当我尝试反序列化XML时,JAXB会抛出javax.xml.bind.UnmarshalException: Unable to create an instance of A
,因为它无法创建抽象类的实例。我想向它展示如何在运行时创建这些实例以便反序列化它们(我有一个特殊的Spring bean,它可以实现它 - 所以我需要能够在我定义创建逻辑的任何地方注入它)我看了JAXB和Jackson ,但找不到怎么做。
有办法吗?我不受任何序列化框架的约束,但最好留在JAXB或Jackson。
答案 0 :(得分:0)
我发现JAXB和杰克逊都能做到。
JAXB提供了两种解决方法:工厂方法和适配器。
使用JAXB工厂方法,我需要创建一个负责对象创建的工厂:
public class MyFactory {
public static MyObject createMyObject() {
return SomeMagic.createMyObject();
}
}
然后我只需要用@XmlType
注释标记我的抽象类:
@XmlType(factoryClass = MyFactory.class, factoryMethod = "createMyObject")
public abstract class MyObject {
...
}
如果我想使用JAXB适配器,我需要创建JAXB可以实例化并从XML填充的Java类,然后我需要将这些类的对象转换为我需要的类:
public class MyAdapter extends XmlAdapter<MyAdapter.MyJaxbObject, MyObject> {
@Override
public MyObject unmarshal(MyJaxbObject src) throws Exception {
MyObject tgt = SomeMagic.createMyObject();
BeanUtils.copyProperties(tgt, src);
return tgt;
}
@Override
public MyObject marshal(MyObject src) throws Exception {
MyJaxbObject tgt = new MyJaxbObject();
BeanUtils.copyProperties(tgt, src);
return tgt;
}
public static class MyJaxbObject {
...
}
}
然后我会用@XmlJavaAdapter
注释标记我的抽象类:
@XmlJavaAdapter(MyAdapter.class)
public abstract class MyObject {
...
}
使用Jackson我可以为我的抽象类创建自定义反序列化器。
public class MyObjectDeserializer extends StdDeserializer<MyObject> {
public MyObjectDeserializer() {
super(MyObject.class);
}
@Override
public MyObject deserialize(JsonParser parser, DeserializationContext context) throws IOException {
ObjectMapper mapper = (ObjectMapper) parser.getCodec();
MyObject myObject = SomeMagic.createMyObject();
return mapper.readerForUpdating(myObject).readValue(parser);
}
}
稍后在我的代码中,我需要注册我的反序列化器:
ObjectMapper mapper = new XmlMapper();
SimpleModule module = new SimpleModule("module", new Version(1, 0, 0, null, null, null));
module.addDeserializer(MyObject.class, new MyObjectDeserializer());
mapper.registerModule(module);
出于我的目的,我更喜欢Jackson自定义反序列化器,因为: