簡體   English   中英

使用 JAXB 從 XML 創建 POJO

[英]Create POJO from XML with JAXB

我正在嘗試使用JAXB庫將Pojo to XML轉換Pojo to XML

我需要最終結果看起來像這樣:

<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();

我試過在聲明中添加一個命名空間標簽:

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

但它只是讓這條線轉換成這個

你離你需要的還差一步......

soap 命名空間是http://schemas.xmlsoap.org/soap/envelope/不是soap所以......如果它會是那樣怎么辦?

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

順便提一句。 但是您真的需要手動創建 SOAP Envelope 嗎? 實際上,標准包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();
        }
    }
}

在你的 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")
    }
)

也看看這個

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM