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



在解组 Soap 响应时,getSOAPBody 返回 null。 我尝试使用XMLStreamReader,它在这种情况下有效。但是我想知道一种通过ByteArrayInputStream的方法。 正确的解决方法是什么。我附在 POJOmand 包信息.java文件下面。

另外,如果我将"xsi:type="xsd:string"设置为"xsi:type="string",它似乎可以工作。我应该如何修改我的 bean 类以使其正常工作?

包装信息.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;

测试JAX.java

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"?>rn"
+ "<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"rn"
+ " xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">rn"
+ "    <soap:Body>rn" + "        <WIResponse xmlns="http://tempuri.org/">rn"
+ "            <WIResult xsi:type="xsd:string">20702458ghhc</WIResult>rn"
+ "        </WIResponse>rn" + "    </soap:Body>rn" + "</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());
}
}

肥皂 XML

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

维斯彭斯.java

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,它可以有一个"阅读器"或"输入流"(在我的例子中,我发现它有一个"输入流"(。InputStream可能是由应用程序类型决定的(在我的例子中,xop + xml,它是"二进制"XML(,但是在测试中,我发现它是ByteInputStream的类型,它是ByteArrayInputStream的扩展类。

最后,您可以将字节数组转换为字符串。此字符串将包含整个 XML(包括 XML 版本标头(,然后可以使用要使用的任何首选 XML 处理程序类对其进行分析。

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

最新更新