2012-12-18 20 views
9

我定義以下類型的模式:與JAXB序列化和任何

<xsd:complexType name="Payload"> 
    <xsd:sequence> 
     <xsd:any namespace="##any" minOccurs="0" maxOccurs="unbounded" processContents="lax"/> 
    </xsd:sequence> 
</xsd:complexType> 

以及創建像這樣的對象:

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(name = "Payload", propOrder = { 
    "any" 
}) 
public class Payload { 

    @XmlAnyElement(lax = true) 
    protected List<Object> any; 
} 

現在我嘗試添加另一個生成的JAXB對象有效載荷做這樣的事情:

Class payloadClass = ...; 
JAXBContext context = JAXBContext.newInstance(WrapperRequest.class, payloadClass); 
... 
marshaller.marshal(wrappedRequest); 

但我得到一個可怕的異常,看起來像它永遠不會因此我決定首先將有效載荷對象序列化爲XML,然後將其作爲有效載荷中的字符串添加。

StringWriter writer = new StringWriter(); 
JAXBContext context = JAXBContext.newInstance(sdoRequest.getClass()); 
Marshaller marshaller = context.createMarshaller(); 
marshaller.marshal(new JAXBElement(new QName("uri", sdoRequest.getClass().getSimpleName()), sdoRequest.getClass(), sdoRequest), writer); 
payload.getAny().add(writer.toString()); 

而這種情況爆發了,「java.lang.String」不包含@XmlRootElement。

那麼如何使用xs:任何有史以來的JAXB?由於JAXB將Payload轉換爲Object,並且它不會序列化Object中的任何內容,所以似乎沒有任何工作要工作。這也是Axis2的全部內容,所以這一點非常具有挑戰性。

+1

當您嘗試將包裝對象添加到Any有效內容時,會得到什麼異常? – gregwhitaker

+1

以下應該有所幫助:http://blog.bdoughan.com/2010/08/using-xmlanyelement-to-build-generic.html –

+0

這是部分的WSDL文件是如何結合在一起,我有零控制。但是,包裝請求是在一個WSDL中定義的,而進入有效負載的請求是在另一個WSDL中定義的。它們都聲明一個BaseRequest,但是當代碼生成時它們是不同的類。我得到這個異常兩個類具有相同的XML類型名稱{http://esp.lala.com/2012/eo}BaseRequest。使用@ XmlType.name和@ XmlType.namespace爲它們分配不同的名稱。 – chubbsondubs

回答

14

下面我將演示JAXB (JSR-222)any一個例子:

有效載荷

any屬性註解與@XmlAnyElement(lax=true)。這意味着如果一個元素通過@XmlRootElement@XmlElementDecl與一個類相關聯,那麼對於該屬性,如果不是該元素將被設置爲org.w3c.dom.Element的實例,則將使用相應對象的實例來填充該屬性。

package forum13941747; 

import java.util.List; 
import javax.xml.bind.annotation.*; 

@XmlRootElement 
@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(name = "Payload", propOrder = { 
    "any" 
}) 
public class Payload { 

    @XmlAnyElement(lax = true) 
    protected List<Object> any; 

} 

下面是與@XmlRootElement註釋的類的一個實例。

package forum13941747; 

import javax.xml.bind.annotation.XmlRootElement; 

@XmlRootElement 
public class Foo { 

} 

酒吧

下面是一類不@XmlRootElement註釋的示例。在這個用例中,我們將利用@XmlRegistry註釋的工廠類別(通常稱爲ObjectFactory)的@XmlElementDecl註釋。

package forum13941747; 

public class Bar { 

} 

的ObjectFactory

下面是指定@XmlElementDecl註解爲Bar類的一個例子。

package forum13941747; 

import javax.xml.bind.JAXBElement; 
import javax.xml.bind.annotation.*; 
import javax.xml.namespace.QName; 

@XmlRegistry 
public class ObjectFactory { 

    @XmlElementDecl(name="bar") 
    public JAXBElement<Bar> createBar(Bar bar) { 
     return new JAXBElement<Bar>(new QName("bar"), Bar.class, bar); 
    } 

} 

的input.xml

下面是我們將使用這個例子中,輸入文檔。有3個元素對應於any屬性。第一個對應Foo類的@XmlRootElement註釋。第二個對應於Bar類的@XmlElementDecl註釋,第三個對應於任何域類。

<?xml version="1.0" encoding="UTF-8"?> 
<payload> 
    <foo/> 
    <bar/> 
    <other/> 
</payload> 

演示

在演示代碼下面我們將解組輸入文檔,然後輸出對象的類在所得any屬性,然後封送​​對象回XML。

package forum13941747; 

import java.io.File; 
import javax.xml.bind.*; 

public class Demo { 

    public static void main(String[] args) throws Exception { 
     JAXBContext jc = JAXBContext.newInstance(Payload.class, Foo.class, ObjectFactory.class); 

     Unmarshaller unmarshaller = jc.createUnmarshaller(); 
     File xml = new File("src/forum13941747/input.xml"); 
     Payload payload = (Payload) unmarshaller.unmarshal(xml); 

     for(Object o : payload.any) { 
      System.out.println(o.getClass()); 
     } 

     Marshaller marshaller = jc.createMarshaller(); 
     marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 
     marshaller.marshal(payload, System.out); 
    } 

} 

輸出

下面是從運行演示代碼的輸出。請注意與any屬性中的對象相對應的類。 foo元素成爲Foo類的一個實例。 bar元素成爲JAXBElement的一個實例,該實例擁有Bar的實例。 other元素成爲org.w3c.dom.Element的一個實例。

class forum13941747.Foo 
class javax.xml.bind.JAXBElement 
class com.sun.org.apache.xerces.internal.dom.ElementNSImpl 
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<payload> 
    <foo/> 
    <bar/> 
    <other/> 
</payload> 
1

。利用對象工廠爲mashelling對象像下面你沒有必要有@XmlRootElement在DemoType.java,

DemoType demoServiceRequest = new DemoType(); 
ObjectFactory obDemo = new ObjectFactory(); 
Request requestObject = new Request();  
requestObject.setAny(obDemo.createDemo(demoServiceRequest)); 

而在Request.java像@XmlSeeAlso添加DemoType類( {DemoType.class})