2017-09-26 113 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