2012-08-15 16 views
9

うまくいけば、簡単なものを検出されません。私はXmlAdapter実装を定義しましたが、それは選択されていないようです。私は単純な自己完結型の例をまとめましたが、これはまだ失敗しています。誰でも私が間違っていることをアドバイスできますか?XmlJavaTypeAdapterは、JAXBの専門家のための

不変なクラス

@XmlJavaTypeAdapter(FooAdapter.class) 
@XmlRootElement 
public class Foo { 
    private final String name; 
    private final int age; 

    public Foo(String name, int age) { 
    this.name = name; 
    this.age = age; 
    } 

    public String getName() { return name; } 
    public int getAge() { return age; } 
} 

アダプタと値タイプ

public class FooAdapter extends XmlAdapter<AdaptedFoo, Foo> { 
    public Foo unmarshal(AdaptedFoo af) throws Exception { 
    return new Foo(af.getName(), af.getAge()); 
    } 

    public AdaptedFoo marshal(Foo foo) throws Exception { 
    return new AdaptedFoo(foo); 
    } 
} 

class AdaptedFoo { 
    private String name; 
    private int age; 

    public AdaptedFoo() {} 

    public AdaptedFoo(Foo foo) { 
    this.name = foo.getName(); 
    this.age = foo.getAge(); 
    } 

    @XmlAttribute 
    public String getName() { return name; } 
    public void setName(String name) { this.name = name; } 

    @XmlAttribute 
    public int getAge() { return age; } 
    public void setAge(int age) { this.age = age; } 
} 

マーシャラー

public class Marshal { 
    public static void main(String[] args) { 
    Foo foo = new Foo("Adam", 34); 

    try { 
     JAXBContext jaxbContext = JAXBContext.newInstance(Foo.class); 
     Marshaller jaxbMarshaller = jaxbContext.createMarshaller(); 

     // output pretty printed 
     jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 

     jaxbMarshaller.marshal(foo, System.out);    
    } catch (JAXBException e) { 
     e.printStackTrace(); 
    } 
    } 
} 

スタックトレース

com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions 
Foo does not have a no-arg default constructor. 
     this problem is related to the following location: 
       at Foo 

     at com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException$Builder.check(IllegalAnnotationsException.java:91) 
     at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(JAXBContextImpl.java:451) 
     at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:283) 
     at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:126) 
     at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1142) 
     at com.sun.xml.internal.bind.v2.ContextFactory.createContext(ContextFactory.java:130) 
     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
     at java.lang.reflect.Method.invoke(Method.java:601) 
     at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:248) 
     at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:235) 
     at javax.xml.bind.ContextFinder.find(ContextFinder.java:445) 
     at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:637) 
     at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:584) 
     at Marshal2.main(Marshal2.java:11) 

私はJDK 1.7.0_05を使用しています注意してください。

答えて

7

次は役立つはず:ROOTオブジェクトとして

FOOは@XmlJavaTypeAdapterは、タイプレベルで指定された場合

それだけでそのクラスを参照するフィールド/プロパティに適用される、としない場合は、そのクラスのインスタンスXMLツリーのルートオブジェクトです。つまり、Fooを自分でAdaptedFooに変換し、AdaptedFooJAXBContextを作成し、Fooではなく作成する必要があります。

元帥

package forum11966714; 

import javax.xml.bind.*; 

public class Marshal { 
    public static void main(String[] args) { 
     Foo foo = new Foo("Adam", 34); 

     try { 
     JAXBContext jaxbContext = JAXBContext.newInstance(AdaptedFoo.class); 
     Marshaller jaxbMarshaller = jaxbContext.createMarshaller(); 

     // output pretty printed 
     jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 

     jaxbMarshaller.marshal(new AdaptedFoo(foo), System.out);    
     } catch (JAXBException e) { 
     e.printStackTrace(); 
     } 
    } 
    } 

AdaptedFoo

あなたはAdaptedFooクラスに@XmlRootElement注釈を追加する必要があります。同じ注釈をFooクラスから削除できます。

package forum11966714; 

import javax.xml.bind.annotation.*; 

@XmlRootElement 
class AdaptedFoo { 
    private String name; 
    private int age; 

    public AdaptedFoo() { 
    } 

    public AdaptedFoo(Foo foo) { 
     this.name = foo.getName(); 
     this.age = foo.getAge(); 
    } 

    @XmlAttribute 
    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    @XmlAttribute 
    public int getAge() { 
     return age; 
    } 

    public void setAge(int age) { 
     this.age = age; 
    } 
} 

FOO AS NESTED OBJECT

Fooがない場合、ルートオブジェクトのすべてはあなたはそれがマッピングされているように動作します。私はあなたのモデルを拡張して、これがどのように機能するかを実証しました。JAXBリファレンス実装はJAXBContextをブートストラップするときにFooクラスを指定できないことを

バー

package forum11966714; 

import javax.xml.bind.annotation.XmlRootElement; 

@XmlRootElement 
public class Bar { 

    private Foo foo; 

    public Foo getFoo() { 
     return foo; 
    } 

    public void setFoo(Foo foo) { 
     this.foo = foo; 
    } 

} 

デモ

注意。

package forum11966714; 

import java.io.File; 

import javax.xml.bind.JAXBContext; 
import javax.xml.bind.JAXBException; 
import javax.xml.bind.Marshaller; 
import javax.xml.bind.Unmarshaller; 

public class Demo { 
    public static void main(String[] args) { 
     try { 
      JAXBContext jaxbContext = JAXBContext.newInstance(Bar.class); 

      Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller(); 
      File xml = new File("src/forum11966714/input.xml"); 
      Bar bar = (Bar) jaxbUnmarshaller.unmarshal(xml); 

      Marshaller jaxbMarshaller = jaxbContext.createMarshaller(); 
      jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 
      jaxbMarshaller.marshal(bar, System.out); 
     } catch (JAXBException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

input.xmlに/出力

<?xml version="1.0" encoding="UTF-8"?> 
<bar> 
    <foo name="Jane Doe" age="35"/> 
</bar> 
+1

おかげブレーズ! (私はあなたが元々見ていたあなたのブログだと思う)。問題は、私がブートストラッピング中にJAXBContextにFoo.classを指定していたようです。 Shame JAXBはこの時点で私がFoo用のアダプタを指定したことでうまくいきません...ブートストラップを少しばかげてしまいます。 – Adamski

関連する問題