जावा में SOAPMessage से रॉ XML प्राप्त करना


79

मैंने JAX-WS में एक SOAP WebServiceProvider स्थापित किया है, लेकिन मुझे पता चल रहा है कि SOAPMessage (या किसी भी नोड) ऑब्जेक्ट से कच्चा XML कैसे प्राप्त किया जाए। यहाँ मैं अभी मिला कोड का एक नमूना है, और जहाँ मैं XML को हथियाने की कोशिश कर रहा हूँ:

@WebServiceProvider(wsdlLocation="SoapService.wsdl")
@ServiceMode(value=Service.Mode.MESSAGE)
public class SoapProvider implements Provider<SOAPMessage>
{
    public SOAPMessage invoke(SOAPMessage msg)
    {
        // How do I get the raw XML here?
    }
}

क्या मूल अनुरोध का XML प्राप्त करने का एक सरल तरीका है? यदि एक अलग प्रकार का प्रदाता (जैसे स्रोत) स्थापित करके कच्चे XML प्राप्त करने का कोई तरीका है, तो मैं वह करने को तैयार हूं।

जवाबों:


152

आप इस तरह से कोशिश कर सकते हैं।

SOAPMessage msg = messageContext.getMessage();
ByteArrayOutputStream out = new ByteArrayOutputStream();
msg.writeTo(out);
String strMsg = new String(out.toByteArray());

4
यह चरित्र एनकोडिंग को ध्यान में नहीं रखता है
आर्टब्रिस्टल

यह डोम ऑब्जेक्ट्स या जैसे निर्माण की तरह कुछ के साथ बहुत स्मृति का उपभोग करेगा? या क्या यह वास्तव में xml को पार्स करने के बिना HTTP प्रतिक्रिया से कच्ची स्ट्रिंग देगा?
रुस्लान

22

यदि आप एक है, तो SOAPMessageया SOAPMessageContext, आप एक का उपयोग कर सकते Transformerहै कि यह एक करने के लिए परिवर्तित करके, Sourceके माध्यम से DOMSource:

            final SOAPMessage message = messageContext.getMessage();
            final StringWriter sw = new StringWriter();

            try {
                TransformerFactory.newInstance().newTransformer().transform(
                    new DOMSource(message.getSOAPPart()),
                    new StreamResult(sw));
            } catch (TransformerException e) {
                throw new RuntimeException(e);
            }

            // Now you have the XML as a String:
            System.out.println(sw.toString());

यह एन्कोडिंग को ध्यान में रखेगा, इसलिए आपके "विशेष वर्ण" आम नहीं होंगे।


प्रदान की जाती है दहन स्मृति-खपत?
lospejos

12

यह पता चलता है कि कोई व्यक्ति इस तरह से प्रोवाइडर <स्रोत> का उपयोग करके कच्चा XML प्राप्त कर सकता है:

import java.io.ByteArrayOutputStream;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.ws.Provider;
import javax.xml.ws.Service;
import javax.xml.ws.ServiceMode;
import javax.xml.ws.WebServiceProvider;

@ServiceMode(value=Service.Mode.PAYLOAD)
@WebServiceProvider()
public class SoapProvider implements Provider<Source>
{
    public Source invoke(Source msg)
    {
        StreamResult sr = new StreamResult();

        ByteArrayOutputStream out = new ByteArrayOutputStream();
        sr.setOutputStream(out);

        try {
            Transformer trans = TransformerFactory.newInstance().newTransformer();
            trans.transform(msg, sr);

            // Use out to your heart's desire.
        }
        catch (TransformerException e) {
            e.printStackTrace();
        }    

        return msg;
    }
}

मैंने समाप्त कर दिया है इस समाधान की आवश्यकता नहीं है, इसलिए मैंने वास्तव में इस कोड को स्वयं करने की कोशिश नहीं की है - इसे सही होने के लिए कुछ ट्विकिंग की आवश्यकता हो सकती है। लेकिन मुझे पता है कि वेब सेवा से कच्चे XML प्राप्त करने के लिए नीचे जाने का यह सही रास्ता है।

(मुझे यकीन नहीं है कि अगर आप बिल्कुल SOAPMessage ऑब्जेक्ट होना चाहिए, तो यह काम कैसे करें, लेकिन फिर, यदि आप कच्चे XML वैसे भी संभालने जा रहे हैं, तो आप उच्च-स्तरीय ऑब्जेक्ट का उपयोग क्यों करेंगे?)


A + संयोजन StringWriterका एक अच्छा विकल्प है , यदि आप XML को सही एन्कोडिंग के साथ चाहते हैंByteArrayOutputStreamStreamResultString
आर्टब्रिस्टल

12

केवल डिबगिंग उद्देश्य के लिए, एक लाइन कोड का उपयोग करें -

msg.writeTo(System.out);


ओपी जरूरी नहीं है कि System.out को डिबगिंग किया जाए (जो कि वेबसर्वर के लिए सुविधाजनक रूप से सुलभ नहीं है) - उसे मूल सॉकेट पर मूल XML भेजने, उसे कहीं स्टोर करने या उसके आँकड़ों की गणना करने की आवश्यकता हो सकती है।
नानोफारड

आप आसानी से एक ByteArrayOutputStreamकन्वर्ट करने के लिए लिख सकते हैं String... मेरे लिए आसान लगता है
vikingsteve

7

यदि आपको xml स्ट्रिंग को xml में स्वरूपित करने की आवश्यकता है, तो यह प्रयास करें:

String xmlStr = "your-xml-string";
Source xmlInput = new StreamSource(new StringReader(xmlStr));
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
transformer.transform(xmlInput,
        new StreamResult(new FileOutputStream("response.xml")));

क्या यह स्वरूपण करने के लिए रिक्त स्थान और टैब के बीच चयन करना संभव है? BTW, मुझे पता है कि टैब संकेत नहीं हैं।
फिलिप जियोसेफिन

7

ट्रांसफार्मर फैक्टरी का उपयोग करना: -

public static String printSoapMessage(final SOAPMessage soapMessage) throws TransformerFactoryConfigurationError,
            TransformerConfigurationException, SOAPException, TransformerException
    {
        final TransformerFactory transformerFactory = TransformerFactory.newInstance();
        final Transformer transformer = transformerFactory.newTransformer();

        // Format it
        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
        transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");

        final Source soapContent = soapMessage.getSOAPPart().getContent();

        final ByteArrayOutputStream streamOut = new ByteArrayOutputStream();
        final StreamResult result = new StreamResult(streamOut);
        transformer.transform(soapContent, result);

        return streamOut.toString();
    }

3

यह काम

 final StringWriter sw = new StringWriter();

try {
    TransformerFactory.newInstance().newTransformer().transform(
        new DOMSource(soapResponse.getSOAPPart()),
        new StreamResult(sw));
} catch (TransformerException e) {
    throw new RuntimeException(e);
}
System.out.println(sw.toString());
return sw.toString();

किसी स्पष्टीकरण की जरूरत नहीं।
मार्टिन केर्स्टन

0

यदि आपके पास क्लाइंट कोड है, तो आपको XML अनुरोध / प्रतिक्रिया प्राप्त करने के लिए बस निम्नलिखित दो पंक्तियों को जोड़ना होगा। यहाँ _callहैorg.apache.axis.client.Call

String request = _call.getMessageContext().getRequestMessage().getSOAPPartAsString();
String response = _call.getMessageContext().getResponseMessage().getSOAPPartAsString();

0

यह बहुत पुराना धागा है, लेकिन हाल ही में मेरा एक ऐसा ही मुद्दा था। मैं एक बाकी सेवा से एक डाउनस्ट्रीम साबुन सेवा को कॉल कर रहा था, और मुझे डाउनस्ट्रीम सर्वर से आने वाली xml प्रतिक्रिया को वापस करने की आवश्यकता है।

इसलिए, मैंने XML प्रतिक्रिया प्राप्त करने के लिए एक SoapMessageContext हैंडलर जोड़ना समाप्त किया। तब मैंने एक विशेषता के रूप में सर्वलेट संदर्भ में प्रतिक्रिया xml को इंजेक्ट किया।

public boolean handleMessage(SOAPMessageContext context) {

            // Get xml response
            try {

                ServletContext servletContext =
                        ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest().getServletContext();

                SOAPMessage msg = context.getMessage();

                ByteArrayOutputStream out = new ByteArrayOutputStream();
                msg.writeTo(out);
                String strMsg = new String(out.toByteArray());

                servletContext.setAttribute("responseXml", strMsg);

                return true;
            } catch (Exception e) {
                return false;
            }
        }

फिर मैंने सर्विस लेयर में xml रिस्पॉन्स स्ट्रिंग को पुनः प्राप्त किया है।

ServletContext servletContext =
                ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest().getServletContext();

        String msg = (String) servletContext.getAttribute("responseXml");

यह अभी तक परीक्षण करने का मौका नहीं था, लेकिन यह दृष्टिकोण थ्रेड सुरक्षित होना चाहिए क्योंकि यह सर्वलेट संदर्भ का उपयोग कर रहा है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.