Java 从SOAP xml解组,getSOAPBody()方法返回Null

Java 从SOAP xml解组,getSOAPBody()方法返回Null,java,xml,xml-parsing,jaxb,pojo,Java,Xml,Xml Parsing,Jaxb,Pojo,在解组Soap响应时,getSOAPBody返回null。 我尝试过使用XMLStreamReader,它在本例中起作用。但我想知道一种通过ByteArrayInputStream实现的方法。 正确的修复方法是什么。我在下面附上POJOmand package-info.java文件 另外,如果我将“xsi:type=“xsd:string”改为“xsi:type=“string”,它似乎可以工作。我应该如何使我的bean类有效 package info.java @XmlSchema(

在解组Soap响应时,getSOAPBody返回null。 我尝试过使用XMLStreamReader,它在本例中起作用。但我想知道一种通过ByteArrayInputStream实现的方法。 正确的修复方法是什么。我在下面附上POJOmand package-info.java文件

另外,如果我将“xsi:type=“xsd:string”改为“xsi:type=“string”,它似乎可以工作。我应该如何使我的bean类有效

package info.java

@XmlSchema(

        namespace = "http://tempuri.org/",

        xmlns = {

                @javax.xml.bind.annotation.XmlNs(prefix = "soap", namespaceURI = "http://schemas.xmlsoap.org/soap/envelope/"),

                @javax.xml.bind.annotation.XmlNs(prefix = "xsi", namespaceURI = "http://www.w3.org/2001/XMLSchema-instance/"),

                @javax.xml.bind.annotation.XmlNs(prefix = "xsd", namespaceURI = "http://www.w3.org/2001/XMLSchema")

        })
package org.tempuri;

import javax.xml.bind.annotation.XmlSchema;
    package org.test;

import java.io.ByteArrayInputStream;
import java.io.IOException;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;
import javax.xml.stream.XMLStreamException;

import org.tempuri.WIResponse;

/**
 * Test Class
 * 
 * @author vijay.prakash
 *
 */
public class TestJAX {
    public static void main(String[] args) throws XMLStreamException, JAXBException, IOException, SOAPException {
        // xmlReadingWay
        /*
         * XMLInputFactory xif = XMLInputFactory.newFactory(); XMLStreamReader xsr =
         * xif.createXMLStreamReader(new FileReader("D:\\BACKUPWARS\\some.xml"));
         * 
         * xsr.nextTag(); // Advance to Envelope tag xsr.nextTag(); // Advance to Body
         * tag xsr.nextTag(); // Advance to getNumberResponconse tag
         */

        // byteway
        String object = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n"
                + "<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"\r\n"
                + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">\r\n"
                + "    <soap:Body>\r\n" + "        <WIResponse xmlns=\"http://tempuri.org/\">\r\n"
                + "            <WIResult xsi:type=\"xsd:string\">20702458ghhc</WIResult>\r\n"
                + "        </WIResponse>\r\n" + "    </soap:Body>\r\n" + "</soap:Envelope>";

        String str = new String(object.getBytes(), "utf-8");
        final MessageFactory messFac = MessageFactory.newInstance();
        SOAPMessage message = messFac.createMessage(null, new ByteArrayInputStream(str.getBytes()));

        message.setProperty(SOAPMessage.CHARACTER_SET_ENCODING, "utf-8");
        System.out.println("message: " + message.getSOAPBody());

        JAXBContext jaxbContext = JAXBContext.newInstance(WIResponse.class);
        Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();

        System.out.println("message.getSOAPBody(): " + message.getSOAPBody());
        Object je = unmarshaller.unmarshal(message.getSOAPBody().extractContentAsDocument());

        WIResponse wi = (WIResponse) je;

        /*
         * //JAXBElement<WIResponse> je =
         * unmarshaller.unmarshal(message.getSOAPBody().extractContentAsDocument(),
         * WIResponse.class);
         */
        System.out.println(wi.getWIResult());

    }
}
    package org.tempuri;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "WIResponse", namespace = "http://tempuri.org/")
public class WIResponse {
    @XmlElement(name = "WIResult", required = true, type = java.lang.String.class)
    String wIResult;

    public String getWIResult() {
        return wIResult;
    }

    public void setWIResult(String wIResult) {
        this.wIResult = wIResult;
    }


}
TestJAX.java

@XmlSchema(

        namespace = "http://tempuri.org/",

        xmlns = {

                @javax.xml.bind.annotation.XmlNs(prefix = "soap", namespaceURI = "http://schemas.xmlsoap.org/soap/envelope/"),

                @javax.xml.bind.annotation.XmlNs(prefix = "xsi", namespaceURI = "http://www.w3.org/2001/XMLSchema-instance/"),

                @javax.xml.bind.annotation.XmlNs(prefix = "xsd", namespaceURI = "http://www.w3.org/2001/XMLSchema")

        })
package org.tempuri;

import javax.xml.bind.annotation.XmlSchema;
    package org.test;

import java.io.ByteArrayInputStream;
import java.io.IOException;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;
import javax.xml.stream.XMLStreamException;

import org.tempuri.WIResponse;

/**
 * Test Class
 * 
 * @author vijay.prakash
 *
 */
public class TestJAX {
    public static void main(String[] args) throws XMLStreamException, JAXBException, IOException, SOAPException {
        // xmlReadingWay
        /*
         * XMLInputFactory xif = XMLInputFactory.newFactory(); XMLStreamReader xsr =
         * xif.createXMLStreamReader(new FileReader("D:\\BACKUPWARS\\some.xml"));
         * 
         * xsr.nextTag(); // Advance to Envelope tag xsr.nextTag(); // Advance to Body
         * tag xsr.nextTag(); // Advance to getNumberResponconse tag
         */

        // byteway
        String object = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n"
                + "<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"\r\n"
                + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">\r\n"
                + "    <soap:Body>\r\n" + "        <WIResponse xmlns=\"http://tempuri.org/\">\r\n"
                + "            <WIResult xsi:type=\"xsd:string\">20702458ghhc</WIResult>\r\n"
                + "        </WIResponse>\r\n" + "    </soap:Body>\r\n" + "</soap:Envelope>";

        String str = new String(object.getBytes(), "utf-8");
        final MessageFactory messFac = MessageFactory.newInstance();
        SOAPMessage message = messFac.createMessage(null, new ByteArrayInputStream(str.getBytes()));

        message.setProperty(SOAPMessage.CHARACTER_SET_ENCODING, "utf-8");
        System.out.println("message: " + message.getSOAPBody());

        JAXBContext jaxbContext = JAXBContext.newInstance(WIResponse.class);
        Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();

        System.out.println("message.getSOAPBody(): " + message.getSOAPBody());
        Object je = unmarshaller.unmarshal(message.getSOAPBody().extractContentAsDocument());

        WIResponse wi = (WIResponse) je;

        /*
         * //JAXBElement<WIResponse> je =
         * unmarshaller.unmarshal(message.getSOAPBody().extractContentAsDocument(),
         * WIResponse.class);
         */
        System.out.println(wi.getWIResult());

    }
}
    package org.tempuri;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "WIResponse", namespace = "http://tempuri.org/")
public class WIResponse {
    @XmlElement(name = "WIResult", required = true, type = java.lang.String.class)
    String wIResult;

    public String getWIResult() {
        return wIResult;
    }

    public void setWIResult(String wIResult) {
        this.wIResult = wIResult;
    }


}

问题似乎是某种解析错误(getSOAPBody()似乎没有正确处理名称空间解析)

解决这个问题的“最简单”的方法是自己从SOAP消息中检索原始XML,然而在典型的Java方式中,这个解决方案是复杂和官僚的

您可能需要修改下面的示例代码:

//https://docs.oracle.com/javase/7/docs/api/javax/xml/soap/SOAPPart.html
javax.xml.soap.SOAPPart GSP = SomeSOAPMessage.getSOAPPart();

//https://static.javadoc.io/com.sun.xml.messaging.saaj/saaj-impl/1.4.0/com/sun/xml/messaging/saaj/util/JAXMStreamSource.html
com.sun.xml.messaging.saaj.util.JAXMStreamSource GC = GSP.getContent();

//https://static.javadoc.io/com.sun.xml.messaging.saaj/saaj-impl/1.4.0/com/sun/xml/messaging/saaj/util/ByteInputStream.html
com.sun.xml.messaging.saaj.util.ByteInputStream BIS = GC.getInputStream();

byte[] ByteArray = BIS.getBytes();

java.lang.String Data = new java.lang.String(ByteArray, "UTF-8");
基本上,SOAPPart从消息中获取SOAPPart的内容,它是一个JAXMStreamSource

然后从JAXMStreamSource,它可以有一个“Reader”或“InputStream”(在我的例子中,我发现它有一个“InputStream”)。InputStream可能由应用程序类型决定(在我的例子中是xop+xml,它是“二进制”xml),但是在测试中我发现它是ByteInputStream类型,它是ByteArrayInputStream的扩展类

最后,可以将ByteArray转换为字符串。这个字符串将包含整个XML(包括XML版本头),然后您可以使用希望使用的任何首选XML处理程序类对其进行解析

(包括全名解析和注释参考,以帮助理解其工作原理。)