2016-07-13 5 views
1

サブタイプがBeanChild1の単純なクラスBean1があります。JAXBリストの@XmlElementタイプを無効にします

@XmlRootElement(name="bean") 
@XmlAccessorType(XmlAccessType.PROPERTY) 
public static class Bean1 
{ 
    public Bean1() 
    { 
    super(); 
    } 

    private List<BeanChild1> childList = new ArrayList<>(); 

    @XmlElement(name="child") 
    public List<BeanChild1> getChildList() 
    { 
    return childList; 
    } 

    public void setChildList(List<BeanChild1> pChildList) 
    { 
    childList = pChildList; 
    } 
} 

public static class BeanChild1 { ... } 

私はクラスのオーバーライドを試みて、リストのタイプを変更しようとしています。 新しい子クラス(BeanChild2)は前の子クラス(つまりBeanChild1)まで拡張されています。

public static class Bean2 extends Bean1 
{ 
    public Bean2() 
    { 
    super(); 
    } 

    @Override 
    @XmlElement(name="child", type=BeanChild2.class) 
    public List<BeanChild1> getChildList() 
    { 
    return super.getChildList(); 
    } 
} 

public static class BeanChild2 extends BeanChild1 { } 

だから、ここで私はそれをテストする方法です:

public static void main(String[] args) 
{ 
    String xml = "<bean>" + 
       " <child></child>" + 
       " <child></child>" + 
       " <child></child>" + 
       "</bean>"; 
    Reader reader = new StringReader(xml); 

    Bean2 b2 = JAXB.unmarshal(reader, Bean2.class); 
    assert b2.getChildList().get(0) instanceof BeanChild2; // fails 
} 

テストでは、このリストには、まだBeanChild1のチャイルズが含まれていることを明らかにしました。

childListフィールドにBeanChild2インスタンスを強制的に挿入するにはどうすればよいですか。

簡単な解決策がない場合、(...例えばXmlAdapter S、Unmarshaller.Listener、親または子クラスで、おそらく追加の注釈を使用して)より創造的なソリューションを投稿すること自由に感じが

答えて

0

方法はありませんスーパークラスのアノテーションを変更する(オーバーライドするなど)。少なくとも注釈を使用しないでください。

  • あなたが使用@XmlAccessorTypeかは重要ではありません(例えばFIELDPROPERTYPUBLICNONE)。
  • アノテーションをフィールドやゲッターに置いても、違いはありません。

ただし、合理的な代替方法があります。 JAXBのMOXy実装は、define the metadata/bindings in an xml fileの機能を提供します。実際、すべてのJavaアノテーションにはXMLの代替手段があります。しかしそれは良くなる:これらのxmlメタデータとJavaアノテーションの両方を組み合わせることができます。クールなことですが、MOXyが両方の宣言をマージし、競合が発生した場合はというXML定義のメタデータが優先されます。

上記のようにBean1クラスに注釈が付けられているとします。次に、XMLファイルでバインディングを再定義することができます。例えば:

<xml-bindings xml-accessor-type="PROPERTY"> 
    <java-types> 
    <java-type name="Bean1"> 
     <xml-element java-attribute="childList" name="child" 
        type="BeanChild2" container-type="java.util.ArrayList" /> 
    </java-type> 
    </java-types> 
</xml-bindings> 

この新しいバインディングファイルをコンテキストオブジェクトの作成時に必要とされています。

// use a map to reference the xml file 
Map<String, Object> propertyMap = new HashMap<>(); 
propertyMap.put(JAXBContextProperties.OXM_METADATA_SOURCE, "bindings.xml"); 

// pass this properyMap during the creation of the JAXB context. 
JAXBContext context = JAXBContext.newInstance(..., propertyMap); 

MOXYは、JavaアノテーションとXMLバインディングをマージします、と矛盾する場合にはXML定義された設定が適用されます。この場合、以前の@XmlElement(name=child)注釈は@XmlElement(name=child, type=BeanChild2.class)に相当するXML定義に置き換えられます。

XMLバインディングhereの詳細を読むことができます。

関連する問題