【问题标题】:How to convert a string to a SOAPMessage in Java?如何在 Java 中将字符串转换为 SOAPMessage?
【发布时间】:2012-11-16 20:39:59
【问题描述】:

我想知道有没有办法将字符串转换为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>";

如何转换字符串?

【问题讨论】:

  • 你可以解析它。或者首先将其构建为消息。

标签: java string soap


【解决方案1】:

将 String 转换为输入流,然后将其读入 SOAP 消息工厂。

InputStream is = new ByteArrayInputStream(send.getBytes());
SOAPMessage request = MessageFactory.newInstance().createMessage(null, is);

You can read about how to do this here.

【讨论】:

  • 非常感谢。还有一个问题:当我创建 SOAPMessageRequest 时,它会自动创建标题和正文。我必须更改字符串的某些部分吗?
  • 已经完成了,先生!但我对删除哪个部分感到困惑。
【解决方案2】:

这对我有用:

SOAPMessage sm = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL).createMessage(new MimeHeaders(), is);

【讨论】:

    【解决方案3】:

    我测量到使用SAXSource 馈送SOAPMessage 比接受答案中使用的内部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();
            }
        }
    
    }
    

    【讨论】:

    • 非常感谢你!我不太关心性能,我只是在做一些测试自动化,但是将文本加载到消息中的能力比各种“addChildElement”要好得多,如果你不知道的话,很难编写脚本提前XML结构!
    【解决方案4】:

    代替:

    System.out.println(response.getContentDescription());
    

    得到响应后用下面一行替换:

    response.writeTo(System.out);
    

    【讨论】:

      【解决方案5】:

      这样你就可以从文件中读取:

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

      【讨论】:

        【解决方案6】:

        我只是想在 Stack-Overflow 中分享我的代码 sn-p,这可能会对某些人有所帮助。

        带有注释的 SOAP-XML 字符串

        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-XML 字符串转换为 SOAP-Message 对象

        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;
        }
        

        将 SOAP-Message 对象转换为 SOPA-XML 字符串

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

        完整示例:

        public class SOAPOperations {
        
            // dependency: groupId:xml-security, artifactId:xmlsec, version:1.3.0
            // dependency: groupId:xalan, artifactId:xalan, version:2.7.1
            public static void main(String[] args) throws Exception {
                
                SOAPOperations obj = new SOAPOperations();
                
                SOAPMessage soapMessage = obj.getSoapMessage(soapXML, true);
                System.out.println("SOAP Message Object:\n"+soapMessage);
                
                String soapMessageStr = obj.getSoapMessage(soapMessage);
                System.out.println("SOAP Message String:\n"+soapMessageStr);
                
                String soapBodyStr = obj.getSoapBody(soapMessage);
                System.out.println("SOAP Body String:\n"+soapBodyStr);
            }
        
            public String getSoapBody(SOAPMessage soapMessage) throws Exception {
                SOAPBody soapEnv = soapMessage.getSOAPBody();
                Document ownerDocument = soapEnv.extractContentAsDocument();
                String stringDocument = toStringDocument(ownerDocument);
                return stringDocument;
            }
            public String getSoapMessage(SOAPMessage soapMessage) throws Exception {
                SOAPEnvelope soapEnv = soapMessage.getSOAPPart().getEnvelope();
                Document ownerDocument = soapEnv.getOwnerDocument();
                String stringDocument = toStringDocument(ownerDocument);
                return stringDocument;
            }
        }
        

        @查看 SOAP 链接

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-06-28
          • 1970-01-01
          • 1970-01-01
          • 2013-03-05
          • 2010-12-18
          相关资源
          最近更新 更多