我想知道有没有办法将字符串转换为 SOAPMessage ?
我说我有一个字符串如下:
String send = "<soap:Envelope xmlns:mrns0=\"http://sdp.SOMETHING.com/mapping/TSO\" xmlns:sdp=\"http://sdp.SOMETHING.com.tr/mapping/generated\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">"
+ "<soap:Header>"
+ "<sdp:token>"
+ "<sdp:sessionId>" + sessionId + "</sdp:sessionId>"
+ "</sdp:token>"
+ "<sdp:transaction-list>"
+ "<sdp:transaction-id>" + 11 + "</sdp:transaction-id>"
+ "</sdp:transaction-list>"
+ "</soap:Header>"
+ "<soap:Body>"
+ "<sdp:SendSMSInput>"
+ "<sdp:EXPIRY_DATE>" + extime + "</sdp:EXPIRY_DATE>"
+ "<sdp:MESSAGE_CLASS>0</sdp:MESSAGE_CLASS>"
+ "<sdp:S_DATE>" + time + "</sdp:S_DATE>"
+ "<sdp:SHORT_NUMBER>1905</sdp:SHORT_NUMBER>"
+ "<sdp:SRC_MSISDN>" + numSend + "</sdp:SRC_MSISDN>"
+ "<sdp:TO_RECEIVERS>"
+ "<sdp:msisdn>" + numSend + "</sdp:msisdn>"
+ "</sdp:TO_RECEIVERS>"
+ "<sdp:MESSAGE_BODY>"
+ "<sdp:message>Message body here.</sdp:message>"
+ "</sdp:MESSAGE_BODY>"
+ "</sdp:SendSMSInput>"
+ "</soap:Body>"
+ "</soap:Envelope>";
当我这样做时:
SOAPConnectionFactory sfc = SOAPConnectionFactory.newInstance();
SOAPConnection connection = sfc.createConnection();
InputStream is = new ByteArrayInputStream(send.getBytes());
SOAPMessage request = MessageFactory.newInstance().createMessage(null, is);
request.removeAllAttachments();
SOAPPart part = request.getSOAPPart();
part.detachNode();
SOAPEnvelope env = part.getEnvelope();
env.detachNode();
SOAPBody body = env.getBody();
body.detachNode();
SOAPHeader head = env.getHeader();
head.detachNode();
request.writeTo(System.out);
URL endpoint = new URL("http://sdp.somewhere.com.tr/view/LbsOpaqueService.wsdl");
SOAPMessage response = connection.call(request, endpoint);
System.out.println(response.getContentDescription());
一切正常。但我仍然从服务器获得NULL
。可能是什么原因?我改变了&lt;和&gt;逃避咒语。
答案 0 :(得分:33)
将String转换为输入流,然后将其读入SOAP消息工厂。
InputStream is = new ByteArrayInputStream(send.getBytes());
SOAPMessage request = MessageFactory.newInstance().createMessage(null, is);
答案 1 :(得分:2)
这对我有用:
SOAPMessage sm = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL).createMessage(new MimeHeaders(), is);
答案 2 :(得分:1)
我测量到SOAPMessage
与SAXSource
的馈送速度比公认的答案中使用的内部SAAJ解析实现快约50%:
SOAPMessage message = messageFactory.createMessage();
message.getSOAPPart().setContent(new SAXSource(new InputSource(new StringReader(send))));
这是测试各种XML解析源和工厂缓存影响的基准测试:
/*
Benchmark (jdk1.8.0_202 32-bit) Mode Cnt Score Error Units
SoapMessageBenchmark.testCreateMessage thrpt 100 4156,685 ? 215,571 ops/s
SoapMessageBenchmark.testCreateMessageWithMessageFactoryNotCached thrpt 100 3709,299 ? 115,495 ops/s
SoapMessageBenchmark.testSetContentDom thrpt 100 5935,972 ? 215,389 ops/s
SoapMessageBenchmark.testSetContentDomWithDocumentBuilderNotCached thrpt 100 3433,539 ? 218,889 ops/s
SoapMessageBenchmark.testSetContentSax thrpt 100 6693,179 ? 319,581 ops/s
SoapMessageBenchmark.testSetContentSaxAndExtractContentAsDocument thrpt 100 4109,924 ? 229,987 ops/s
SoapMessageBenchmark.testSetContentStax thrpt 100 5126,822 ? 249,648 ops/s
SoapMessageBenchmark.testSetContentStaxWithXmlInputFactoryNotCached thrpt 100 4630,860 ? 235,773 ops/s
*/
package org.sample;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Timeout;
import org.openjdk.jmh.annotations.Warmup;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPConstants;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.util.StreamReaderDelegate;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stax.StAXSource;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.TimeUnit;
@BenchmarkMode(Mode.Throughput)
@Warmup(iterations = 10, time = 100, timeUnit = TimeUnit.MILLISECONDS)
@Measurement(iterations = 10, time = 100, timeUnit = TimeUnit.MILLISECONDS)
@Timeout(time = 10)
public class SoapMessageBenchmark {
private static MessageFactory messageFactory;
private static DocumentBuilder documentBuilder;
private static XMLInputFactory xmlInputFactory;
static {
try {
documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
messageFactory = MessageFactory.newInstance(SOAPConstants.SOAP_1_1_PROTOCOL);
xmlInputFactory = XMLInputFactory.newInstance();
} catch (SOAPException | ParserConfigurationException e) {
throw new IllegalStateException(e);
}
}
@State(Scope.Benchmark)
public static class S {
byte[] bytes = ("<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">\n" +
" <soap:Header>\n" +
" <ResponseHeader xmlns=\"https://www.google.com/apis/ads/publisher/v201905\">\n" +
" <requestId>xxxxxxxxxxxxxxxxxxxx</requestId>\n" +
" <responseTime>1063</responseTime>\n" +
" </ResponseHeader>\n" +
" </soap:Header>\n" +
" <soap:Body>\n" +
" <getAdUnitsByStatementResponse xmlns=\"https://www.google.com/apis/ads/publisher/v201905\">\n" +
" <rval>\n" +
" <totalResultSetSize>1</totalResultSetSize>\n" +
" <startIndex>0</startIndex>\n" +
" <results>\n" +
" <id>2372</id>\n" +
" <name>RootAdUnit</name>\n" +
" <description></description>\n" +
" <targetWindow>TOP</targetWindow>\n" +
" <status>ACTIVE</status>\n" +
" <adUnitCode>1002372</adUnitCode>\n" +
" <inheritedAdSenseSettings>\n" +
" <value>\n" +
" <adSenseEnabled>true</adSenseEnabled>\n" +
" <borderColor>FFFFFF</borderColor>\n" +
" <titleColor>0000FF</titleColor>\n" +
" <backgroundColor>FFFFFF</backgroundColor>\n" +
" <textColor>000000</textColor>\n" +
" <urlColor>008000</urlColor>\n" +
" <adType>TEXT_AND_IMAGE</adType>\n" +
" <borderStyle>DEFAULT</borderStyle>\n" +
" <fontFamily>DEFAULT</fontFamily>\n" +
" <fontSize>DEFAULT</fontSize>\n" +
" </value>\n" +
" </inheritedAdSenseSettings>\n" +
" </results>\n" +
" </rval>\n" +
" </getAdUnitsByStatementResponse>\n" +
" </soap:Body>\n" +
"</soap:Envelope>").getBytes();
}
@Benchmark
public SOAPBody testCreateMessage(S s) throws SOAPException, IOException {
try (InputStream inputStream = new ByteArrayInputStream(s.bytes)) {
SOAPMessage message = messageFactory.createMessage(null, inputStream);
return message.getSOAPBody();
}
}
@Benchmark
public SOAPBody testCreateMessageWithMessageFactoryNotCached(S s) throws SOAPException, IOException {
MessageFactory messageFactory = MessageFactory.newInstance(SOAPConstants.SOAP_1_1_PROTOCOL);
try (InputStream inputStream = new ByteArrayInputStream(s.bytes)) {
SOAPMessage message = messageFactory.createMessage(null, inputStream);
return message.getSOAPBody();
}
}
@Benchmark
public SOAPBody testSetContentDom(S s) throws SOAPException, IOException, SAXException {
try (InputStream inputStream = new ByteArrayInputStream(s.bytes)) {
Document document = documentBuilder.parse(inputStream);
SOAPMessage message = messageFactory.createMessage();
message.getSOAPPart().setContent(new DOMSource(document));
return message.getSOAPBody();
}
}
@Benchmark
public SOAPBody testSetContentDomWithDocumentBuilderNotCached(S s) throws SOAPException, IOException, SAXException, ParserConfigurationException {
DocumentBuilder documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
try (InputStream inputStream = new ByteArrayInputStream(s.bytes)) {
Document document = documentBuilder.parse(inputStream);
SOAPMessage message = messageFactory.createMessage();
message.getSOAPPart().setContent(new DOMSource(document));
return message.getSOAPBody();
}
}
@Benchmark
public SOAPBody testSetContentSax(S s) throws SOAPException, IOException {
try (InputStream inputStream = new ByteArrayInputStream(s.bytes)) {
SOAPMessage message = messageFactory.createMessage();
message.getSOAPPart().setContent(new SAXSource(new InputSource(inputStream)));
return message.getSOAPBody();
}
}
@Benchmark
public Document testSetContentSaxAndExtractContentAsDocument(S s) throws SOAPException, IOException {
try (InputStream inputStream = new ByteArrayInputStream(s.bytes)) {
SOAPMessage message = messageFactory.createMessage();
message.getSOAPPart().setContent(new SAXSource(new InputSource(inputStream)));
return message.getSOAPBody().extractContentAsDocument();
}
}
@Benchmark
public SOAPBody testSetContentStax(S s) throws SOAPException, IOException, XMLStreamException {
try (InputStream inputStream = new ByteArrayInputStream(s.bytes)) {
XMLStreamReader xmlStreamReader = new StreamReaderDelegate(xmlInputFactory.createXMLStreamReader(inputStream)) {
@Override
public String getVersion() {
return "1.1";
}
};
SOAPMessage message = messageFactory.createMessage();
message.getSOAPPart().setContent(new StAXSource(xmlStreamReader));
return message.getSOAPBody();
}
}
@Benchmark
public SOAPBody testSetContentStaxWithXmlInputFactoryNotCached(S s) throws SOAPException, IOException, XMLStreamException {
XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
try (InputStream inputStream = new ByteArrayInputStream(s.bytes)) {
XMLStreamReader xmlStreamReader = new StreamReaderDelegate(xmlInputFactory.createXMLStreamReader(inputStream)) {
@Override
public String getVersion() {
return "1.1";
}
};
SOAPMessage message = messageFactory.createMessage();
message.getSOAPPart().setContent(new StAXSource(xmlStreamReader));
return message.getSOAPBody();
}
}
}
答案 3 :(得分:0)
而不是:
System.out.println(response.getContentDescription());
获得回复后将其替换为以下行:
response.writeTo(System.out);
答案 4 :(得分:0)
这样你就可以从文件中读取:
byte[] encoded = Files.readAllBytes(Paths.get("C:/resources/soap/RequestFileReply.xml"));
InputStream bStream = new ByteArrayInputStream(encoded);
SOAPMessage request = MessageFactory.newInstance().createMessage(null, bStream);
SOAPBody body = request.getSOAPBody();
答案 5 :(得分:0)
我只想在Stack-Overflow中共享我的代码段,这可能对某些人有所帮助。
带注释的SOAP-XML字符串
@protocol DetailsTableViewCellDelegate <NSObject>
- (void) customCell:(DetailsTableViewCell *)cell yesBtnPressed:(bool)yes;
@property (nonatomic, retain) NSString * yesChecked;
将SOAP-XML字符串转换为SOAP-Message对象
static boolean OMIT_XML_DECLARATION = true;
static String soapXML = "<env:Envelope xmlns:env=\"http://www.w3.org/2003/05/soap-envelope\">"
+ "<env:Body> "
+ "<product version=\"11.1.2.4.0\"> <!-- Data XML -->"
+ "<name>API Gateway</name> <company>Oracle</company> <description>SOA Security and Management</description>"
+ "</product> </env:Body> </env:Envelope>";
将SOAP消息对象转换为SOPA-XML字符串
public SOAPMessage getSoapMessage(String xmlData, boolean isToIgnoringComments) throws Exception {
if (isToIgnoringComments) {
Document doc = getDocument(xmlData); // SOAP MSG removing comment elements
xmlData = toStringDocument(doc);
}
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(xmlData.getBytes());
MimeHeaders mimeHeaders = new MimeHeaders();
SOAPMessage message = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL).createMessage(mimeHeaders, byteArrayInputStream);
return message;
}
public static Document getDocument(String xmlData) throws Exception {
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
dbFactory.setNamespaceAware(true);
dbFactory.setIgnoringComments(true);
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
InputSource ips = new org.xml.sax.InputSource(new StringReader(xmlData));
Document doc = dBuilder.parse(ips);
return doc;
}
完整示例:
public static String toStringDocument(Document doc) throws TransformerException {
StringWriter sw = new StringWriter();
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
if (OMIT_XML_DECLARATION) {
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
} else {
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
}
transformer.setOutputProperty(OutputKeys.METHOD, "xml");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
transformer.transform(new DOMSource(doc), new StreamResult(sw));
return sw.toString(); // sw.getBuffer().toString();
}
@请参阅SOAP链接