MOXyを使用して、この質問で説明されていることを正確に実行しようとしています。しかし、私はいくつかの異なる動作をしていますが、結果は同じです。うまくいきません。
@XmlElements を使用し、concrete クラスごとに @XmlElement に名前と型を追加しました。アダプターのないすべてのクラスでは完璧に機能しますが、PolyAdapter を使用するクラスでは機能しません。
私の場合、オブジェクトをマーシャリングするためにアダプターが呼び出されます。しかし、それが書き込むのは、このような xml ファイルへのエントリだけです。
<?xml version="1.0" encoding="UTF-8"?>
<fooContainer>
<poly PolyName="PolyN$1">ABCBCD</poly>
<cPlexPoly>moxy.CPlexPoly$CPlexPolyAdapter$CCPWrapper@480bdb19</cPlexPoly>
</fooContainer>
アンマーシャラーはまったく呼び出されません。
MOXy 2.5.0 と現在の RC3 2.5.1 をテストしましたが、どちらの場合も結果は同じでした。デバッグ出力も有効にしましたが、警告やエラーはありません。
または、これを機能させる別の方法があるかもしれません
更新 1:モデルの提供
MOXy 2.5.0での問題を示す小さな例を作成しました
インターフェース:
@XmlRootElement
public interface Foo {
public List<String> getCoordinates();
}
XmlAdapter のないクラス:
@XmlRootElement(name="poly")
public class Poly implements Foo {
@XmlAttribute
String PolyName = "PolyN$1";
@XmlAnyElement
private List<String> coordinates = new LinkedList<>();
@Override
public List<String> getCoordinates() {
return coordinates;
}
public void addCoordinate( final String poly ) {
coordinates.add( poly );
}
}
XmlAdapter を持つクラス:
@XmlJavaTypeAdapter(CPlexPolyAdapter.class)
public class CPlexPoly implements Foo {
private Map<String, String> values = new HashMap<>();
@Override
public List<String> getCoordinates() {
return new ArrayList<>(values.values());
}
public void addCoordinate( final String poly ) {
values.put( Integer.toString( poly.hashCode()), poly );
}
public List<String> getKeys() {
return new ArrayList<>(values.keySet());
}
public static class CPlexPolyAdapter extends XmlAdapter<CCPWrapper, CPlexPoly> {
@XmlRootElement(name="wrapper")
public static class CCPWrapper {
@XmlAnyElement
List<String> keys = new ArrayList<>();
@XmlAnyElement
List<String> values = new ArrayList<>();
}
@Override
public CPlexPoly unmarshal(CCPWrapper v) throws Exception {
// Won't be called.
return null;
}
@Override
public CCPWrapper marshal(CPlexPoly v) throws Exception {
if( v == null ) {
return null;
}
CCPWrapper wrapper = new CCPWrapper();
wrapper.values.addAll( v.getCoordinates() );
wrapper.keys.addAll( v.getKeys() );
return wrapper;
}
}
}
単純なコンテナ クラス:
@XmlRootElement(name="fooContainer")
public class FooContainer {
@XmlElements({
@XmlElement(name = "poly", type = Poly.class),
@XmlElement(name = "cPlexPoly", type = CPlexPoly.class)
})
public List<Foo> container = new LinkedList<>();
}
主要:
public class Main {
public static void main(String[] args) {
FooContainer fc = new FooContainer();
Poly poly = new Poly();
poly.addCoordinate("ABC");
poly.addCoordinate("BCD");
CPlexPoly cpoly = new CPlexPoly();
cpoly.addCoordinate("XYZ");
cpoly.addCoordinate("WXY");
fc.container.add( poly );
fc.container.add( cpoly );
/* Marshall */
JAXBContext context;
try {
context = JAXBContext.newInstance( FooContainer.class );
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal( fc, new FileWriter("fc.xml") );
}
catch (JAXBException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
/* UnMarshall */
}
}
上記の結果も更新しました。どうも。
更新 2:簡素化されたラッパー
属性のみを含むこの単純なラッパーでも、何も変わりません。
@XmlJavaTypeAdapter(CPlexPolyAdapter.class)
public class CPlexPoly implements Foo {
private Map<String, String> values = new HashMap<>();
@Override
public List<String> getCoordinates() {
return new ArrayList<>(values.values());
}
public void addCoordinate( final String poly ) {
values.put( Integer.toString( poly.hashCode()), poly );
}
public List<String> getKeys() {
return new ArrayList<>(values.keySet());
}
public static class CPlexPolyAdapter extends XmlAdapter<CCPWrapper, CPlexPoly> {
@XmlRootElement(name="wrapper")
public static class CCPWrapper {
@XmlAttribute
String test = "test";
}
@Override
public CPlexPoly unmarshal(CCPWrapper v) throws Exception {
// Won't be called.
return null;
}
@Override
public CCPWrapper marshal(CPlexPoly v) throws Exception {
if( v == null ) {
return null;
}
CCPWrapper wrapper = new CCPWrapper();
return wrapper;
}
}
}
したがって、誰かが何が間違っているのかを知っていれば、それは非常に役に立ちます。ありがとうクリスチャン