次の例を検討してください。
ClassAとそれを拡張したClassBがあります。私の問題は、xml ファイルからClassBをアンマーシャリングする必要があることです。ClassAは私の管理下にないため、変更できないことに注意してください。
この例では、いくつかの問題が指摘されています。
主な問題は、ClassAには、アダプターなしで JAXB に必要なデフォルトの引数なしコンストラクターがないことです。したがって、 ClassBをJAXB で問題なく処理できる単純なクラスValBにマップするMyAdapterを実装しました。
主な問題は、JAXB にこのアダプターを使用させる方法ですか? クラスレベルで@XmlJavaTypeAdapterを定義すること も、アダプターをアンマーシャラーに登録することもありません。
アンマーシャラーがClassAのインスタンスであるオブジェクトを返すように、JAXB にMyAdapterを使用させる方法を知っている人はいますか?
public class JaxbTest {
public static abstract class ClassA {
public ClassA(String id) {
}
}
@XmlRootElement
@XmlJavaTypeAdapter(MyAdapter.class) // does not have an effect
public static class ClassB extends ClassA {
public String text;
public ClassB() {
super("");
}
}
public static class ValB {
public String text;
}
public static class MyAdapter extends XmlAdapter<ValB, ClassB> {
@Override
public ClassB unmarshal(ValB v) throws Exception {
ClassB b = new ClassB();
b.text = v.text;
return b;
}
@Override
public ValB marshal(ClassB v) throws Exception {
ValB b = new ValB();
b.text = v.text;
return b;
}
}
public static void main(String[] args) {
try {
JAXBContext context = JAXBContext.newInstance(ClassB.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
unmarshaller.setAdapter(new MyAdapter()); // does not have an effect
ClassA a = (ClassA) unmarshaller.unmarshal(new File("test.xml"));
// do somthing with a
} catch (Exception e) {
e.printStackTrace();
}
}
}
ところで: コードをあまり深刻に考えないでください。これは、問題を示す単なる例です。ClassAとClassBの定義があまり役に立たないことはわかっています。