2017-09-26 102 views
1

我試圖使用JAXB庫轉換Pojo to XML使用JAXB從XML創建POJO

我需要的最終結果是這個樣子:

<soap:Envelope 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
     xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> 
<soap:Body> 

<!--other stuff--> 

</soap:Body> 
</soap:Envelope> 

我已經嘗試了幾種不同的方法,但到目前爲止,我沒有成功,這是我的最新嘗試。

@XmlRootElement(name = "soap:Envelope") 
public class Envelope { 

    private SoapBody soapBody; 

    public String toString() { 
     return "ClassPojo [SoapBody = " + soapBody + "]"; 
    } 

    public SoapBody getSoapBody() { 
     return soapBody; 
    } 

    @XmlElement(name = "soap:Body") 
    public void setSoapBody(SoapBody soapBody) { 
     this.soapBody = soapBody; 
    } 
} 

這個轉換得到以下結果(但它缺少XMLNS線):

<soap:Envelope> 
<soap:Body> 
<!--Other stuff--> 
</soap:Body> 
</soap:Envelope> 

我已經嘗試添加一個命名空間標籤聲明:

@XmlRootElement(name = "soap:Envelope", namespace = "soap")

但它只是將行轉換爲此<ns2:soap:Envelope xmlns:ns2="soap">

編輯:

OutputStream os = connection.getOutputStream(); 
    JAXBContext jaxbContext = 
     JAXBContext.newInstance(MyOtherStuffObject.class); 
    Marshaller marshaller = jaxbContext.createMarshaller(); 
    marshaller.marshal(myObject, os); 
    os.flush(); 
+0

soap命名空間是否必須是顯式的?對於大多數解析器,應該等同於。 –

回答

1

我已經嘗試添加一個命名空間標籤的聲明一看:

@XmlRootElement(name = 「肥皂:信封」,命名空間= 「肥皂」 )

,但它只是做行轉換爲該

你是在一步走出你所需要的...

肥皂命名空間是http://schemas.xmlsoap.org/soap/envelope/不是soap所以......如果它會是這樣的?

@XmlRootElement(name = "soap:Envelope", namespace = "http://schemas.xmlsoap.org/soap/envelope/")

BTW。但是您是否真的需要手動創建SOAP信封?實際上標準包javax.xml.soap已經可以與SOAP一起工作了,您可以將「其他內容」封裝到SOAP Envelope中,而不必關心自己構建它。

更新: 我強烈建議使用SOAP的Web服務的工作,如Apache CXF或這樣的,而不是在低級別操作SOAP時使用正常的框架。

但是可以用標準的JDK類來完成。 示例代碼:

package com.foo.tests; 

import java.io.ByteArrayOutputStream; 
import java.util.Calendar; 
import java.util.UUID; 

import javax.xml.bind.JAXBContext; 
import javax.xml.bind.JAXBElement; 
import javax.xml.parsers.DocumentBuilderFactory; 
import javax.xml.soap.MessageFactory; 
import javax.xml.soap.SOAPConstants; 
import javax.xml.soap.SOAPMessage; 

import org.w3c.dom.Document; 

public class TestSOAPMessage { 

    static MessageFactory factory; 
    static DocumentBuilderFactory documentFactory; 
    static JAXBContext jaxbCtx; 
    static com.foo.tests.pojo.ObjectFactory myStuffFactory = new com.foo.tests.pojo.ObjectFactory(); 
    static { 
     try { 
      factory = MessageFactory.newInstance(SOAPConstants.SOAP_1_1_PROTOCOL); 
      documentFactory = DocumentBuilderFactory.newInstance(); 
      jaxbCtx = JAXBContext.newInstance(com.foo.tests.pojo.MyStuffPojo.class); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

    public static void main(String... args) { 
     try { 
      // prepare test MyStuff JAXB POJO 
      com.foo.tests.pojo.MyStuffPojo myStuff = myStuffFactory.createMyStuffPojo(); 
      // populate myStuff Pojo 
      myStuff.setMyPropertyA("property A"); 
      myStuff.setTimestamp(Calendar.getInstance()); 
      myStuff.setMessageId(UUID.randomUUID().toString()); 
      //--- 
      // marshal JAXB Pojo to DOM Document 
      Document myStuffDoc = documentFactory.newDocumentBuilder().newDocument(); 

      //*** myStuff has @XmlRootElement annotation 
      jaxbCtx.createMarshaller().marshal(myStuff, myStuffDoc); 

      //*** myStuff does not have @XmlRootElement annotation wrap it and use JAXBElement instead 
//   JAXBElement<com.foo.tests.pojo.MyStuffPojo myStuff> jaxbWrapper = myStuffFactory.createMyStuffPojo(myStuff); 
//   jaxbCtx.createMarshaller().marshal(jaxbWrapper, myStuffDoc); 

      //marshal JAXB Pojo to DOM Document 
      Document myStuffDoc = documentFactory.newDocumentBuilder().newDocument(); 
      jaxbCtx.createMarshaller().marshal(jaxbWrapper, myStuffDoc); 
      //Create SOAPMessage 
      SOAPMessage myMessage = factory.createMessage(); 
      //Optional if we'd like to set those properties... 
      myMessage.setProperty(SOAPMessage.WRITE_XML_DECLARATION, "true"); 
      myMessage.setProperty(SOAPMessage.CHARACTER_SET_ENCODING, "utf-8"); 
      // set myStuff into SOAPBody 
      myMessage.getSOAPBody().addDocument(myStuffDoc);   
      //All done. Save changes 
      myMessage.saveChanges(); 

      // Just for test: print message 
      ByteArrayOutputStream finalBos = new ByteArrayOutputStream(); 
      myMessage.writeTo(finalBos); 
      System.out.println("my Message: \r\n" + new String(finalBos.toByteArray())); 

     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 
} 
+0

我喜歡關於不手動創建SOAP信封的想法,我已經在編組代碼中添加了這個問題,我將如何改變它以將信封添加到它? –

0

關於你的java bean添加namespace屬性是什麼?或者

JAXB還提供@XMLSchema註釋,我們可以使用它來生成命名空間。

你可以做如下。

@javax.xml.bind.annotation.XmlSchema(namespace="http://www.springframework.org/schema/beans" , elementFormDefault=javax.xml.bind.annotation.XmlNsForm.QUALIFIED, 
    xmlns={  @javax.xml.bind.annotation.XmlNs(namespaceURI="http://www.w3.org/2001/XMLSchema-instance", prefix="xsi"), 
    @javax.xml.bind.annotation.XmlNs(namespaceURI="http://schemas.xmlsoap.org/soap/envelope/", prefix="soap") 
    } 
) 

也對this