سؤال

ولقد اقامة WebServiceProvider SOAP في JAX-WS، ولكن أواجه صعوبة في معرفة كيفية الحصول على XML الخام من SOAPMessage (أو أي عقدة) الكائن. وفيما يلي عينة من قانون عندي الآن، وحيث أحاول انتزاع 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 الخام من خلال إنشاء نوع مختلف من مزود (مثل المصدر)، وسأكون على استعداد للقيام بذلك أيضا.

هل كانت مفيدة؟

المحلول 3

وتبين أن واحدا يمكن الحصول على 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 الخام على أي حال، لماذا كنت تستخدم كائن المستوى العالي؟ )

نصائح أخرى

هل يمكن أن محاولة في هذا السبيل.

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

إذا كان لديك 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());

وهذا سيستغرق الترميز في الاعتبار، لذلك سيكون لديك "أحرف خاصة" لم يحصل المهترئ.

ولمجرد تصحيح الغرض، استخدام رمز سطر واحد -

وmsg.writeTo(System.out);

إذا كنت بحاجة إلى تنسيق سلسلة أكس أكس ل، حاول هذا:

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

وعن طريق محول مصنع: -

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

وهذا يعمل

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

وإذا كان لديك رمز العميل ثم تحتاج فقط إلى إضافة السطرين التاليين للحصول على طلب XML / الاستجابة. هنا _call org.apache.axis.client.Call

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

ومن قديم جدا ولكن في الآونة الأخيرة كان لي مشكلة مشابهة. كنت استدعاء خدمة الصابون المصب، من خدمة الراحة، وأنا في حاجة للعودة استجابة أكس القادمة من خادم المصب كما هو.

وهكذا، انتهى بي الأمر إضافة معالج 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;
            }
        }

وبعد ذلك لقد استرداد سلسلة استجابة أكس في طبقة الخدمة.

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

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

لم يكن لديهم فرصة لاختبار حتى الآن ولكن هذا النهج يجب أن يكون الخيط آمنة لأنه يستخدم السياق بريمج.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top