JAX-WS के साथ XML अनुरोध / प्रतिक्रियाओं को ट्रेस करना


172

क्या JAX-WS संदर्भ कार्यान्वयन (JDK 1.5 और बेहतर में शामिल एक) के साथ प्रकाशित webservice के लिए कच्चे अनुरोध / प्रतिक्रिया XML तक पहुंचने के लिए एक आसान तरीका (उर्फ: प्रॉक्सी का उपयोग नहीं करना) है? कोड के माध्यम से ऐसा करने में सक्षम होने के नाते मुझे वह करने की आवश्यकता है। बस इसे चतुर लॉगिंग विन्यास द्वारा एक फ़ाइल में लॉग इन किया जाना अच्छा होगा लेकिन पर्याप्त है।

मुझे पता है कि अन्य अधिक जटिल और पूर्ण रूपरेखाएं मौजूद हैं जो ऐसा कर सकती हैं, लेकिन मैं इसे जितना संभव हो उतना सरल रखना चाहूंगा और अक्ष, cxf, आदि सभी काफी उपरि जोड़ सकते हैं जिससे मैं बचना चाहता हूं।

धन्यवाद!


5
बस एक नोट: JAX-WS एक मानक है, जिसे CXF लागू करता है।
बूझो

जावा सिस्टम प्रॉपर्टीज़ और एनवायरनमेंट वेरिएबल सेट करना देखें: <br> stackoverflow.com/questions/7054972/…
Dafka

जवाबों:


282

निम्नलिखित विकल्प कंसोल में सभी संचारों को लॉग करने में सक्षम करते हैं (तकनीकी रूप से, आपको इनमें से केवल एक की आवश्यकता है, लेकिन यह आपके द्वारा उपयोग किए जाने वाले पुस्तकालयों पर निर्भर करता है, इसलिए सभी चार को सुरक्षित करना विकल्प है)। आप इसे कोड में सेट कर सकते हैं जैसे कि उदाहरण में, या कमांड लाइन पैरामीटर के रूप में -D का उपयोग कर या जैसा कि उपेंद्र ने लिखा है।

System.setProperty("com.sun.xml.ws.transport.http.client.HttpTransportPipe.dump", "true");
System.setProperty("com.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.dump", "true");
System.setProperty("com.sun.xml.ws.transport.http.HttpAdapter.dump", "true");
System.setProperty("com.sun.xml.internal.ws.transport.http.HttpAdapter.dump", "true");
System.setProperty("com.sun.xml.internal.ws.transport.http.HttpAdapter.dumpTreshold", "999999");

जब विवरण के लिए त्रुटि होती है , तो प्रश्न को ट्रेसिंग XML अनुरोध / JAX-WS के साथ प्रतिक्रियाएं देखें।


7
धन्यवाद, यह सबसे अच्छा जवाब है जो मुझे इस समस्या से मिला है
एम स्मिथ

5
यह मेरे लिए काम नहीं करता, जब CLIENT टॉमकैट में चलता है। केवल -D सामान काम करता है। मेरा मानना ​​है कि यह टॉमकैट में क्लासऑलर-संरचना के कारण है?
रोप

3
System.setProperty ("com.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.dump", "true"); JDK7 में बंडल किया गया सही JAX-WS 2.2 RI है और डिफ़ॉल्ट रूप से उपयोग किया जाता है
Glenn Bech

1
टोमैट में इस काम के लिए आपको इन कमांड्स को जोड़ने की जरूरत है उत्प्रेरित में JAVA_OPTS। उदा। पहली पंक्ति में जोड़ें: JAVA_OPTS = "-Dcom.sun.xml.ws.transport.http.client.HttpTransportPipe.dump = true -Dcom। sun.xml.internal.ws.transport.http.client.HttpTransportPipe.dump = true -Dcom.sun.xml.ws.transport.http.HttpAdapter.dump = true -Dcom.sun.xml.internal.ws.transport। http.HttpAdapter.dump = true "उसके बाद आप catalina.out की जांच कर सकते हैं और इस से आउटपुट वहां दिखाई देगा।
Reece

4
साथ ही System.setProperty ("com.sun.xml.internal.ws.transport.http.HttpAdapter.dumpTreshold", "999999") जोड़ें; अनुरोध और प्रतिक्रिया उत्पादन कम नहीं है
8bitme

84

यहाँ कच्चे कोड में समाधान है (stjohnroe और शमीक के लिए एक साथ धन्यवाद):

Endpoint ep = Endpoint.create(new WebserviceImpl());
List<Handler> handlerChain = ep.getBinding().getHandlerChain();
handlerChain.add(new SOAPLoggingHandler());
ep.getBinding().setHandlerChain(handlerChain);
ep.publish(publishURL);

जहां SOAPLoggingHandler है (लिंक किए गए उदाहरणों से फट गया):

package com.myfirm.util.logging.ws;

import java.io.PrintStream;
import java.util.Map;
import java.util.Set;

import javax.xml.namespace.QName;
import javax.xml.soap.SOAPMessage;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;

/*
 * This simple SOAPHandler will output the contents of incoming
 * and outgoing messages.
 */
public class SOAPLoggingHandler implements SOAPHandler<SOAPMessageContext> {

    // change this to redirect output if desired
    private static PrintStream out = System.out;

    public Set<QName> getHeaders() {
        return null;
    }

    public boolean handleMessage(SOAPMessageContext smc) {
        logToSystemOut(smc);
        return true;
    }

    public boolean handleFault(SOAPMessageContext smc) {
        logToSystemOut(smc);
        return true;
    }

    // nothing to clean up
    public void close(MessageContext messageContext) {
    }

    /*
     * Check the MESSAGE_OUTBOUND_PROPERTY in the context
     * to see if this is an outgoing or incoming message.
     * Write a brief message to the print stream and
     * output the message. The writeTo() method can throw
     * SOAPException or IOException
     */
    private void logToSystemOut(SOAPMessageContext smc) {
        Boolean outboundProperty = (Boolean)
            smc.get (MessageContext.MESSAGE_OUTBOUND_PROPERTY);

        if (outboundProperty.booleanValue()) {
            out.println("\nOutbound message:");
        } else {
            out.println("\nInbound message:");
        }

        SOAPMessage message = smc.getMessage();
        try {
            message.writeTo(out);
            out.println("");   // just to add a newline
        } catch (Exception e) {
            out.println("Exception in handler: " + e);
        }
    }
}

8
यदि आप अभी भी उपरोक्त कोड के साथ प्रतिक्रिया / अनुरोध xml नहीं देखते हैं तो लिंक देखें: stackoverflow.com/questions/2808544/…
ian_scho

2
यह SOAPMessage ऑब्जेक्ट के अस्तित्व पर निर्भर करता है, इसलिए यह विफल हो जाएगा (यदि आप सर्वर से विकृत प्रतिक्रिया प्राप्त करते हैं, तो केवल एक अपवाद प्रिंट करें, लेकिन ट्रेस नहीं)। अगर आपको गला गलत लगता है, तो भी आपको ट्रेस की जरूरत है, मेरे जवाब की जाँच करें।
मि। नेपिक

शीर्ष पर स्निपेट में: अंतिम पंक्ति के बारे में ep.publish(publishURL);: क्या है publishURL(मेरे कोड में, wsdl url को सेवा में ही शामिल किया गया है; मेरे पास कोई url नहीं है। मुझे क्या याद है?)
badera

यदि आप इसे सभी इंटरफ़ेस पर प्रकाशित करना चाहते हैं, तो publishUrl कुछ इस तरह है (hltp = http): "hltp: //0.0.0.0: 8080 / स्टैंडअलोन / सेवा"। इस विशेष मामले में, आप "hltp: //127.0.0.1: 8080 / स्टैंडअलोन / सेवा / yourService" पर सेवा का उपयोग कर सकते हैं जहां "yourService" wsdl में परिभाषित wsdl पोर्ट स्थान है।
रिस्कॉप

@ Mr.Napik: लेकिन इस तरह से आप अभी भी अपनी लॉगिंग सुविधा प्रदान कर सकते हैं, जो लॉगिंग फ्रेमवर्क का उपयोग करते समय अच्छा है।
डैनियल

54

JAVA_OPTSटॉमकैट शुरू करने से पहले, लिनक्स एनवीएस में नीचे सेट करें। फिर टॉमकैट शुरू करें। आपको catalina.outफ़ाइल में अनुरोध और प्रतिक्रिया दिखाई देगी ।

export JAVA_OPTS="$JAVA_OPTS -Dcom.sun.xml.ws.transport.http.client.HttpTransportPipe.dump=true"

3
प्रतिभाशाली। यह सबसे अच्छा जवाब है IMHO।
पाब्लो सांता क्रूज़

किसी कारण से, मेरे लिए यह है:-Dcom.sun.xml.ws.transport.http.client.HttpTransportPipe.dump=true
टिब्बी

किसी कारण से, इसने मेरी 3 वेब सेवाओं में से केवल एक पर काम किया (मेरे टॉमकैट वेब-ऐप में 3 JAX-WS वेब सेवाएँ हैं)। किसी भी विचार क्यों यह सभी 3 पर काम नहीं करेगा?
डेविड ब्रॉसार्ड

मेरे लिए यह देखने के लिए ठीक काम किया गया कि मेरा परीक्षण विफल क्यों हुआ (मेरे परीक्षण के 'रन कॉन्फ़िगरेशन' में विकल्प को 'वीएम तर्क' के रूप में सेट करें)।
MrSmith42

तुम बस कभी सबसे अच्छा जवाब के साथ इंटरनेट exploeded प्रजनक
vikingsteve

16

निम्नलिखित सिस्टम गुण सेट करें, यह xml लॉगिंग को सक्षम करेगा। आप इसे जावा या कॉन्फ़िगरेशन फ़ाइल में सेट कर सकते हैं।

static{
        System.setProperty("com.sun.xml.ws.transport.http.client.HttpTransportPipe.dump", "true");
        System.setProperty("com.sun.xml.ws.transport.http.HttpAdapter.dump", "true");
        System.setProperty("com.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.dump", "true");
        System.setProperty("com.sun.xml.internal.ws.transport.http.HttpAdapter.dump", "true");
        System.setProperty("com.sun.xml.internal.ws.transport.http.HttpAdapter.dumpTreshold", "999999");
    }

कंसोल लॉग:

INFO: Outbound Message
---------------------------
ID: 1
Address: http://localhost:7001/arm-war/castService
Encoding: UTF-8
Http-Method: POST
Content-Type: text/xml
Headers: {Accept=[*/*], SOAPAction=[""]}
Payload: xml
--------------------------------------
INFO: Inbound Message
----------------------------
ID: 1
Response-Code: 200
Encoding: UTF-8
Content-Type: text/xml; charset=UTF-8
Headers: {content-type=[text/xml; charset=UTF-8], Date=[Fri, 20 Jan 2017 11:30:48 GMT], transfer-encoding=[chunked]}
Payload: xml
--------------------------------------

14

इंजेक्षन SOAPHandlerइंटरफ़ेस समाप्ति बिंदु को। हम SOAP अनुरोध और प्रतिक्रिया का पता लगा सकते हैं

कार्यक्रम के साथ SOAPHandler को लागू करना

ServerImplService service = new ServerImplService();
Server port = imgService.getServerImplPort();
/**********for tracing xml inbound and outbound******************************/
Binding binding = ((BindingProvider)port).getBinding();
List<Handler> handlerChain = binding.getHandlerChain();
handlerChain.add(new SOAPLoggingHandler());
binding.setHandlerChain(handlerChain);

@HandlerChain(file = "handlers.xml")अपने समापन बिंदु इंटरफ़ेस में एनोटेशन जोड़कर घोषणा

handlers.xml

<?xml version="1.0" encoding="UTF-8"?>
<handler-chains xmlns="http://java.sun.com/xml/ns/javaee">
    <handler-chain>
        <handler>
            <handler-class>SOAPLoggingHandler</handler-class>
        </handler>
    </handler-chain>
</handler-chains>

SOAPLoggingHandler.java

/*
 * This simple SOAPHandler will output the contents of incoming
 * and outgoing messages.
 */


public class SOAPLoggingHandler implements SOAPHandler<SOAPMessageContext> {
    public Set<QName> getHeaders() {
        return null;
    }

    public boolean handleMessage(SOAPMessageContext context) {
        Boolean isRequest = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
        if (isRequest) {
            System.out.println("is Request");
        } else {
            System.out.println("is Response");
        }
        SOAPMessage message = context.getMessage();
        try {
            SOAPEnvelope envelope = message.getSOAPPart().getEnvelope();
            SOAPHeader header = envelope.getHeader();
            message.writeTo(System.out);
        } catch (SOAPException | IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return true;
    }

    public boolean handleFault(SOAPMessageContext smc) {
        return true;
    }

    // nothing to clean up
    public void close(MessageContext messageContext) {
    }

}

मैं बिल्कुल इसका पालन कर रहा हूं। मैं शीर्ष लेख में संशोधन करने के बाद संदेश को प्रिंट कर रहा हूं, हालांकि मैं उन परिवर्तनों को नहीं देख रहा हूं। ऐसा लगता है जैसे कि संदेश तब तक नहीं बदलता है जब तक कि यह हैंडल को छोड़ नहीं देता है। मेसेजेज विधि
Iofacture

यदि मैं दो बार संदेश प्रिंट करने के लिए कॉल करता हूं, तो दूसरी बार अपडेट होता है। बहुत विषम
Iofacture

11

इस कार्यक्रम को करने के विभिन्न तरीके हैं, जैसा कि अन्य उत्तरों में वर्णित है, लेकिन वे काफी आक्रामक तंत्र हैं। हालांकि, यदि आप जानते हैं कि आप JAX-WS RI (उर्फ "मेट्रो") का उपयोग कर रहे हैं, तो आप इसे कॉन्फ़िगरेशन स्तर पर कर सकते हैं। ऐसा करने के निर्देश के लिए यहां देखें । अपने आवेदन के साथ गड़बड़ करने की कोई जरूरत नहीं है।


2
मेट्रो = JAX-WS RI + WSIT (यानी JAX-WS RI! = मेट्रो)
पास्कल थिवेंट

@Pau: फिक्स्ड। तुम्हें पता है, इसके लिए मुझे वोट करने के बजाय, आप एक वैकल्पिक लिंक का सुझाव देने और सुझाव देने में थोड़ा प्रयास कर सकते थे।
skaffman 16

1
अगर मुझे एक मिल गया था, तो सुनिश्चित करें कि मैंने इसे रखा होगा। इसे व्यक्तिगत न मानें। हटाए गए वोट;)
पाऊ

लिंक फिर से टूट गया है (java.net के साथ क्या हो रहा है ???)। मुझे लगता है कि यह नई कड़ी है: metro.java.net/nonav/1.2/guide/Logging.html
sdoca

9

// यह समाधान प्रोग्राम को वेब सर्विस क्लिन w / o XML कॉन्फिगर करने के लिए प्रोग्रामर को जोड़ने का एक तरीका प्रदान करता है

// यहाँ पूर्ण दस्तावेज़ देखें: http://docs.oracle.com/cd/E17904_01//web.1111/e13734/handlers.htm#i222476

// SOAPHandler को लागू करने वाला नया वर्ग बनाएं

public class LogMessageHandler implements SOAPHandler<SOAPMessageContext> {

@Override
public Set<QName> getHeaders() {
    return Collections.EMPTY_SET;
}

@Override
public boolean handleMessage(SOAPMessageContext context) {
    SOAPMessage msg = context.getMessage(); //Line 1
    try {
        msg.writeTo(System.out);  //Line 3
    } catch (Exception ex) {
        Logger.getLogger(LogMessageHandler.class.getName()).log(Level.SEVERE, null, ex);
    } 
    return true;
}

@Override
public boolean handleFault(SOAPMessageContext context) {
    return true;
}

@Override
public void close(MessageContext context) {
}
}

// प्रोग्रामेटिक रूप से अपना LogMessageHandler जोड़ें

   com.csd.Service service = null;
    URL url = new URL("https://service.demo.com/ResService.svc?wsdl");

    service = new com.csd.Service(url);

    com.csd.IService port = service.getBasicHttpBindingIService();
    BindingProvider bindingProvider = (BindingProvider)port;
    Binding binding = bindingProvider.getBinding();
    List<Handler> handlerChain = binding.getHandlerChain();
    handlerChain.add(new LogMessageHandler());
    binding.setHandlerChain(handlerChain);

4

मैं एक नया उत्तर पोस्ट कर रहा हूं, क्योंकि मेरे पास एंटोनियो द्वारा प्रदान की गई टिप्पणी पर पर्याप्त प्रतिष्ठा नहीं है (देखें: https://stackoverflow.com/a/1957777 )।

यदि आप चाहते हैं कि SOAP संदेश एक फ़ाइल में मुद्रित किया जाए (जैसे कि Log4j के माध्यम से), तो आप उपयोग कर सकते हैं:

OutputStream os = new ByteArrayOutputStream();
javax.xml.soap.SOAPMessage soapMsg = context.getMessage();
soapMsg.writeTo(os);
Logger LOG = Logger.getLogger(SOAPLoggingHandler.class); // Assuming SOAPLoggingHandler is the class name
LOG.info(os.toString());

कृपया ध्यान दें कि कुछ परिस्थितियों में, विधि callTo () अपेक्षित रूप से व्यवहार नहीं कर सकती है (देखें: https://community.oracle.com/thread/1123104?tstart=0 या https://www.java.net/node / 691073 ), इसलिए निम्नलिखित कोड चाल करेगा:

javax.xml.soap.SOAPMessage soapMsg = context.getMessage();
com.sun.xml.ws.api.message.Message msg = new com.sun.xml.ws.message.saaj.SAAJMessage(soapMsg);
com.sun.xml.ws.api.message.Packet packet = new com.sun.xml.ws.api.message.Packet(msg);
Logger LOG = Logger.getLogger(SOAPLoggingHandler.class); // Assuming SOAPLoggingHandler is the class name
LOG.info(packet.toString());

2

आपको एक javax.xml.ws.handler.LogicalHandler को लागू करने की आवश्यकता है, इस हैंडलर को फिर एक हैंडलर कॉन्फ़िगरेशन फ़ाइल में संदर्भित किया जाना चाहिए, जो कि आपकी सेवा समापन बिंदु (इंटरफ़ेस या कार्यान्वयन) में @HandlerChain एनोटेशन द्वारा संदर्भित है। फिर आप या तो संदेश को system.out के माध्यम से आउटपुट कर सकते हैं या अपने प्रक्रिया कार्यान्वयन में एक लकड़हारा।

देख

http://publib.boulder.ibm.com/infocenter/wasinfo/v7r0/index.jsp?topic=/com.ibm.websphere.express.doc/info/exp/ae/twbs_jaxwshandler.html

http://java.sun.com/mailers/techtips/enterprise/2006/TechTips_June06.html


2

यहां सूचीबद्ध उत्तर जो आपको उपयोग करने के लिए मार्गदर्शन करते SOAPHandlerहैं, पूरी तरह से सही हैं। उस दृष्टिकोण का लाभ यह है कि यह किसी भी JAX-WS कार्यान्वयन के साथ काम करेगा, क्योंकि SOAPHandler JAX-WS विनिर्देशन का हिस्सा है। हालाँकि, SOAPHandler के साथ समस्या यह है कि यह पूरी तरह से मेमोरी में पूरे XML संदेश का प्रतिनिधित्व करने का प्रयास करता है। इससे विशाल मेमोरी उपयोग हो सकता है। JAX-WS के विभिन्न कार्यान्वयनों ने इसके लिए अपने स्वयं के वर्कआर्ड को जोड़ा है। यदि आप बड़े अनुरोधों या बड़ी प्रतिक्रियाओं के साथ काम करते हैं, तो आपको मालिकाना दृष्टिकोणों में से एक पर गौर करने की आवश्यकता है।

चूँकि आप "JDK 1.5 या बेहतर में शामिल एक" के बारे में पूछते हैं, इसलिए मैं JAX-WS RI (उर्फ मेट्रो) के रूप में जो औपचारिक रूप से जाना जाता है, के संबंध में जवाब दूंगा जो कि JDK के साथ शामिल है।

JAX-WS RI के पास इसके लिए एक विशिष्ट समाधान है जो स्मृति उपयोग के मामले में बहुत कुशल है।

Https://javaee.github.io/metro/doc/user-guide/ch02.html#efficient-handlers-in-jax-ws-ri देखें । दुर्भाग्य से वह लिंक अब टूट गया है लेकिन आप इसे वेकबैक मशीन पर पा सकते हैं। मैं नीचे हाइलाइट्स दूंगा:

2007 में मेट्रो के लोगों ने एक अतिरिक्त हैंडलर प्रकार पेश कियाMessageHandler<MessageHandlerContext> , जो मेट्रो का मालिकाना हक है। यह कहीं अधिक कुशल है SOAPHandler<SOAPMessageContext>क्योंकि यह इन-मेमोरी डोम प्रतिनिधित्व करने की कोशिश नहीं करता है।

यहाँ मूल ब्लॉग लेख से महत्वपूर्ण पाठ है:

MessageHandler:

JAX-WS विशिष्टता और RI में बेहतर संदेश अमूर्त द्वारा प्रदान किए गए एक्स्टेंसिबल हैंडलर ढांचे का उपयोग करते हुए, हमने MessageHandlerआपके वेब सेवा अनुप्रयोगों का विस्तार करने के लिए एक नया हैंडलर बुलाया । MessageHandler SOAPHandler के समान है, सिवाय इसके कि इसके कार्यान्वयन को पहुँच प्राप्त होती हैMessageHandlerContext(MessageContext का विस्तार)। MessageHandlerContext के माध्यम से कोई भी संदेश तक पहुंच सकता है और संदेश एपीआई का उपयोग करके इसे संसाधित कर सकता है। जैसा कि मैंने ब्लॉग के शीर्षक में रखा है, यह हैंडलर आपको संदेश पर काम करने देता है, जो संदेश को केवल DOM आधारित संदेश ही नहीं बल्कि एक्सेस / प्रोसेस करने के लिए कुशल तरीके प्रदान करता है। हैंडलर का प्रोग्रामिंग मॉडल समान है और संदेश हैंडलर मानक लॉजिकल और सोप हैंडलर के साथ मिलाया जा सकता है। मैंने JAX-WS RI 2.1.3 में एक नमूना जोड़ा है जो संदेश लॉग करने के लिए MessageHandler का उपयोग दिखा रहा है और यहाँ नमूने से एक स्निपेट है:

public class LoggingHandler implements MessageHandler<MessageHandlerContext> {
    public boolean handleMessage(MessageHandlerContext mhc) {
        Message m = mhc.getMessage().copy();
        XMLStreamWriter writer = XMLStreamWriterFactory.create(System.out);
        try {
            m.writeTo(writer);
        } catch (XMLStreamException e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    public boolean handleFault(MessageHandlerContext mhc) {
        ..... 
        return true;
    }

    public void close(MessageContext messageContext) {    }

    public Set getHeaders() {
        return null;
    }
}

(2007 ब्लॉग पोस्ट से अंतिम उद्धरण)

LoggingHandlerउदाहरण के लिए, अपने कस्टम हैंडलर को कहने की आवश्यकता नहीं है, किसी भी प्रभाव के लिए आपके हैंडलर चेन में शामिल होने की आवश्यकता है। यह किसी भी अन्य को जोड़ने के समान है Handler, इसलिए आप इस पृष्ठ पर अन्य उत्तरों में देख सकते हैं कि यह कैसे करना है।

आप मेट्रो गिटहब रेपो में एक पूर्ण उदाहरण पा सकते हैं ।


1

आप वेब सेवा के ServletFilterसामने एक डालने का प्रयास कर सकते हैं और सेवा से जाने / वापस आने के अनुरोध और प्रतिक्रिया का निरीक्षण कर सकते हैं।

यद्यपि आपने विशेष रूप से एक प्रॉक्सी के लिए नहीं पूछा था, कभी-कभी मुझे लगता है कि कनेक्शन पर जाने के लिए tcptrace पर्याप्त है। यह एक सरल उपकरण है, कोई इंस्टॉल नहीं है, यह डेटा स्ट्रीम दिखाता है और फ़ाइल भी लिख सकता है।


1

में क्रम तो आप बस पर अमल कर सकता है

com.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.dump = true

के रूप में डंप एक सार्वजनिक वर वर्ग में परिभाषित किया गया इस प्रकार है

public static boolean dump;

मेरे लिए com.sun.xml.ws.transport.http.client.HttpTransportPipe.dump = true के साथ काम करें;
userfb

1

क्या मैं यह समझने में सही हूं कि आप कच्चे XML संदेश को बदलना / एक्सेस करना चाहते हैं?

यदि ऐसा है, तो आप (या चूंकि यह पांच साल पुराना है, अगला लड़का) प्रदाता इंटरफ़ेस पर एक नज़र रखना चाहता है जो JAXWS का हिस्सा है। क्लाइंट का प्रतिरूप "डिस्पैच" वर्ग का उपयोग करके किया जाता है। वैसे भी, आपको हैंडलर या इंटरसेप्टर नहीं जोड़ना है। आप अभी भी कर सकते हैं, बिल्कुल। नकारात्मक पक्ष यह है कि आप SOAPMessage के निर्माण के लिए पूरी तरह से जिम्मेदार हैं, लेकिन यह आसान है, और यदि आप चाहते हैं कि यह (जैसा मैंने किया) यह एकदम सही है।

यहां सर्वर साइड के लिए एक उदाहरण है (बिट अनाड़ी, यह सिर्फ प्रयोग करने के लिए था) -

@WebServiceProvider(portName="Provider1Port",serviceName="Provider1",targetNamespace = "http://localhost:8123/SoapContext/SoapPort1")
@ServiceMode(value=Service.Mode.MESSAGE)
public class Provider1 implements Provider<SOAPMessage>
{
  public Provider1()
  {
  }

  public SOAPMessage invoke(SOAPMessage request)
  { try{


        File log= new File("/home/aneeshb/practiceinapachecxf/log.txt");//creates file object
        FileWriter fw=new FileWriter(log);//creates filewriter and actually creates file on disk

            fw.write("Provider has been invoked");
            fw.write("This is the request"+request.getSOAPBody().getTextContent());

      MessageFactory mf = MessageFactory.newInstance();
      SOAPFactory sf = SOAPFactory.newInstance();

      SOAPMessage response = mf.createMessage();
      SOAPBody respBody = response.getSOAPBody();
      Name bodyName = sf.createName("Provider1Insertedmainbody");
      respBody.addBodyElement(bodyName);
      SOAPElement respContent = respBody.addChildElement("provider1");
      respContent.setValue("123.00");
      response.saveChanges();
      fw.write("This is the response"+response.getSOAPBody().getTextContent());
      fw.close();
      return response;}catch(Exception e){return request;}


   }
}

आप इसे एक एसईआई की तरह प्रकाशित करेंगे,

public class ServerJSFB {

    protected ServerJSFB() throws Exception {
        System.out.println("Starting Server");
        System.out.println("Starting SoapService1");

        Object implementor = new Provider1();//create implementor
        String address = "http://localhost:8123/SoapContext/SoapPort1";

        JaxWsServerFactoryBean svrFactory = new JaxWsServerFactoryBean();//create serverfactorybean

        svrFactory.setAddress(address);
        svrFactory.setServiceBean(implementor);

        svrFactory.create();//create the server. equivalent to publishing the endpoint
        System.out.println("Starting SoapService1");
  }

public static void main(String args[]) throws Exception {
    new ServerJSFB();
    System.out.println("Server ready...");

    Thread.sleep(10 * 60 * 1000);
    System.out.println("Server exiting");
    System.exit(0);
}
}

या आप इसके लिए एक समापन बिंदु वर्ग का उपयोग कर सकते हैं। आशा है कि मददगार रहे हैं।

और ओह, यदि आप चाहते हैं कि आपको हेडर और सामान से निपटने की ज़रूरत नहीं है, यदि आप सर्विस मोड को PAYLOAD में बदलते हैं (आपको केवल साबुन बॉडी मिलेगी)।


1

logback.xml कॉन्फ़िगरेशन फ़ाइलों के साथ, आप कर सकते हैं:

<logger name="com.sun.xml.internal.ws.transport.http.client.HttpTransportPipe" level="trace" additivity="false">
    <appender-ref ref="STDOUT"/>
</logger>

यह अनुरोध और प्रतिक्रिया को इस तरह लॉग करेगा (लॉग आउटपुट के लिए आपके कॉन्फ़िगरेशन पर निर्भर करता है):

09:50:23.266 [qtp1068445309-21] DEBUG c.s.x.i.w.t.h.c.HttpTransportPipe - ---[HTTP request - http://xyz:8081/xyz.svc]---
Accept: application/soap+xml, multipart/related
Content-Type: application/soap+xml; charset=utf-8;action="http://xyz.Web.Services/IServiceBase/GetAccessTicket"
User-Agent: JAX-WS RI 2.2.9-b130926.1035 svn-revision#5f6196f2b90e9460065a4c2f4e30e065b245e51e
<?xml version="1.0" ?><S:Envelope xmlns:S="http://www.w3.org/2003/05/soap-envelope">[CONTENT REMOVED]</S:Envelope>--------------------

09:50:23.312 [qtp1068445309-21] DEBUG c.s.x.i.w.t.h.c.HttpTransportPipe - ---[HTTP response - http://xyz:8081/xyz.svc - 200]---
null: HTTP/1.1 200 OK
Content-Length: 792
Content-Type: application/soap+xml; charset=utf-8
Date: Tue, 12 Feb 2019 14:50:23 GMT
Server: Microsoft-IIS/10.0
X-Powered-By: ASP.NET
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">[CONTENT REMOVED]</s:Envelope>--------------------

1

मैं कुछ दिनों के लिए वेब सेवा साबुन अनुरोध और प्रतिक्रिया में प्रवेश करने के लिए कुछ रूपरेखा पुस्तकालय खोजने की कोशिश कर रहा था। नीचे दिए गए कोड ने मेरे लिए समस्या तय कर दी:

System.setProperty("com.sun.xml.ws.transport.http.client.HttpTransportPipe.dump", "true");
        System.setProperty("com.sun.xml.ws.transport.http.HttpAdapter.dump", "true");
        System.setProperty("com.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.dump", "true");
        System.setProperty("com.sun.xml.internal.ws.transport.http.HttpAdapter.dump", "true");

0

एक तरीका यह है कि आप अपने कोड का उपयोग नहीं कर रहे हैं, लेकिन एथरल या वायरशर्क जैसे नेटवर्क पैकेट स्नीफ़र्स का उपयोग करें जो कि XML संदेश के साथ HTTP पैकेट को पेलोड के रूप में कैप्चर कर सकते हैं और आप उन्हें एक फ़ाइल या तो लॉग करना रख सकते हैं।

लेकिन अधिक परिष्कृत दृष्टिकोण अपने संदेश संचालकों को लिखना है। आप इसे यहाँ देख सकते हैं ।


0

वास्तव में। यदि आप HttpClientTransport के स्रोतों पर गौर करते हैं तो आप देखेंगे कि यह java.util.log.ogger में संदेश भी लिख रहा है। जिसका अर्थ है कि आप उन संदेशों को अपने लॉग में भी देख सकते हैं।

उदाहरण के लिए, यदि आप Log4J2 का उपयोग कर रहे हैं, तो आपको बस इतना करना चाहिए:

  • अपनी कक्षा पथ में JUL-Log4J2 पुल जोड़ें
  • com.sun.xml.internal.ws.transport.http.client पैकेज के लिए TRACE स्तर सेट करें।
  • add -jjava.util.log.manager = org.apache.log.log4j.jul.LogManager सिस्टम प्रॉपर्टी आपके ऐप्लिकेशन के लिए कमांड लाइन शुरू करती है

इन चरणों के बाद आप अपने लॉग में SOAP संदेश देखना शुरू करते हैं।


0

इस सूत्र में सोपहैंडलर्स का उपयोग करके कुछ उत्तर दिए गए हैं। आपको पता होना चाहिए कि SoapHandlers संदेश को संशोधित करता है यदिwriteTo(out) कहा जाता है।

SOAPMessage की writeTo(out)विधि को कॉल करना स्वचालित रूप से कॉल करता हैsaveChanges() विधि भी । परिणामस्वरूप सभी संदेश में MTOM / XOP बाइनरी डेटा संलग्न है।

मुझे यकीन नहीं है कि ऐसा क्यों हो रहा है, लेकिन यह एक प्रलेखित विशेषता है।

इसके अलावा, यह विधि उस बिंदु को चिह्नित करती है जिस पर सभी घटक अटैचमेंटपार्ट ऑब्जेक्ट के डेटा को संदेश में खींच लिया जाता है।

https://docs.oracle.com/javase/7/docs/api/javax/xml/soap/SOAPMessage.html#saveChanges ()


0

यदि आप IBM लिबर्टी ऐप सर्वर चलाते हैं, तो बस ibm-ws-bnd.xml को WEB-INF निर्देशिका में जोड़ें।

<?xml version="1.0" encoding="UTF-8"?>
<webservices-bnd
    xmlns="http://websphere.ibm.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://websphere.ibm.com/xml/ns/javaee http://websphere.ibm.com/xml/ns/javaee/ibm-ws-bnd_1_0.xsd"
    version="1.0">
    <webservice-endpoint-properties
        enableLoggingInOutInterceptor="true" />
</webservices-bnd>
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.