Verfolgung von XML-Anfragen / -Antworten mit JAX-WS

172

Gibt es eine einfache Möglichkeit (auch bekannt als: kein Proxy verwenden), um Zugriff auf das unformatierte Anforderungs- / Antwort-XML für einen Webservice zu erhalten, der mit der JAX-WS-Referenzimplementierung veröffentlicht wurde (die in JDK 1.5 und höher enthalten ist)? Das über Code tun zu können, ist das, was ich tun muss. Nur durch clevere Protokollierungskonfigurationen in einer Datei protokolliert zu werden, wäre schön, aber genug.

Ich weiß, dass es andere komplexere und vollständigere Frameworks gibt, die dies tun könnten, aber ich möchte es so einfach wie möglich halten und Achse, CXF usw. verursachen einen erheblichen Overhead, den ich vermeiden möchte.

Vielen Dank!

Antonio
quelle
5
Nur eine Anmerkung: JAX-WS ist ein Standard, den CXF implementiert.
Bozho
Festlegen von Java-Systemeigenschaften und Umgebungsvariablen siehe: <br> stackoverflow.com/questions/7054972/…
Dafka

Antworten:

282

Die folgenden Optionen ermöglichen die Protokollierung der gesamten Kommunikation an der Konsole (technisch gesehen benötigen Sie nur eine davon, dies hängt jedoch von den verwendeten Bibliotheken ab, sodass die Einstellung aller vier sicherer ist). Sie können es im Code wie im Beispiel oder als Befehlszeilenparameter mit -D oder als Umgebungsvariable festlegen, wie Upendra geschrieben hat.

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

Weitere Informationen finden Sie in der Frage Verfolgen von XML-Anforderungen / -Antworten mit JAX-WS, wenn ein Fehler auftritt .

Herr Napik
quelle
7
Danke, dies ist die beste Antwort, die ich auf dieses Problem gefunden habe
M Smith
5
Dies funktioniert bei mir NICHT, wenn der CLIENT in Tomcat ausgeführt wird. Nur das -D Zeug funktioniert. Ich glaube das liegt an der classLoader-Struktur in Tomcat?
Rop
3
System.setProperty ("com.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.dump", "true"); ist das richtige für JAX-WS 2.2 RI, das in JDK7 gebündelt und standardmäßig verwendet wird
Glenn Bech
1
Für diese Arbeit in Tomcat müssen Sie diese Befehle zu JAVA_OPTS in catalogina.sh hinzufügen, z. B. in der ersten Zeile hinzufügen: 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 "Danach können Sie Catalina.out überprüfen und die Ausgabe davon wird dort angezeigt.
Reece
4
Fügen Sie außerdem System.setProperty hinzu ("com.sun.xml.internal.ws.transport.http.HttpAdapter.dumpTreshold", "999999"); um die Anforderungs- und Antwortausgabe nicht abgeschnitten zu haben
8bitme
84

Hier ist die Lösung in Rohcode (zusammengestellt dank stjohnroe und Shamik):

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

Wo sich SOAPLoggingHandler befindet (aus verknüpften Beispielen herausgerissen):

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);
        }
    }
}
Antonio
quelle
8
Siehe Link, wenn Sie immer noch keine Antwort- / Anforderungs-XML mit dem obigen Code sehen: stackoverflow.com/questions/2808544/…
ian_scho
2
Dies hängt von der Existenz eines SOAPMessage-Objekts ab, sodass es fehlschlägt (drucken Sie nur eine Ausnahme, aber nicht die Ablaufverfolgung), wenn Sie eine fehlerhafte Antwort vom Server erhalten. Überprüfen Sie meine Antwort, wenn Sie eine Spur benötigen, auch wenn Thigns schief gehen.
Herr Napik
Im Snippet oben: in Bezug auf die letzte Zeile ep.publish(publishURL);: Was ist publishURL(In meinem Code ist die WSDL-URL im Dienst selbst enthalten; ich habe keine URL außerhalb. Was vermisse ich?)
badera
Wenn Sie es auf allen Schnittstellen veröffentlichen möchten, lautet die PublishUrl ungefähr so ​​(hltp = http): "hltp: //0.0.0.0: 8080 / standalone / service". In diesem speziellen Fall können Sie unter "hltp: //127.0.0.1: 8080 / standalone / service / yourService" auf den Dienst zugreifen, wobei "yourService" der in der wsdl definierte wsdl-Portspeicherort ist.
Riskop
@ Mr.Napik: Aber auf diese Weise können Sie immer noch Ihre eigene Protokollierungsfunktion bereitstellen, was hilfreich ist, wenn Sie ein Protokollierungsframework verwenden.
Daniel
54

JAVA_OPTSStellen Sie vor dem Starten von Tomcat die folgenden Einstellungen in Linux envs ein. Starten Sie dann Tomcat. Sie sehen die Anfrage und Antwort in der catalina.outDatei.

export JAVA_OPTS="$JAVA_OPTS -Dcom.sun.xml.ws.transport.http.client.HttpTransportPipe.dump=true"
Upendra
quelle
3
Brillant. Dies ist meiner Meinung nach die beste Antwort.
Pablo Santa Cruz
Aus irgendeinem Grund ist es für mich:-Dcom.sun.xml.ws.transport.http.client.HttpTransportPipe.dump=true
Tibo
Aus irgendeinem Grund funktionierte dies nur bei einem meiner 3 Webdienste (ich habe 3 JAX-WS-Webdienste in meiner Tomcat-Web-App). Irgendeine Idee, warum es nicht bei allen 3 funktionieren würde?
David Brossard
Es hat gut funktioniert, um zu sehen, warum mein Test fehlgeschlagen ist (Setzen Sie die Option in der 'Konfiguration ausführen' meines Tests als 'VM-Argument').
MrSmith42
Ihr Vater hat gerade das Internet mit der besten Antwort aller Zeiten
ausgenutzt
16

Legen Sie die folgenden Systemeigenschaften fest. Dadurch wird die XML-Protokollierung aktiviert. Sie können es in Java oder Konfigurationsdatei einstellen.

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

Konsolenprotokolle:

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
--------------------------------------
2787184
quelle
14

Injizieren SOAPHandlerin Endpunktschnittstelle. Wir können die SOAP-Anforderung und -Antwort verfolgen

SOAPHandler mit Programmatic implementieren

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

Deklarativ durch Hinzufügen von @HandlerChain(file = "handlers.xml")Anmerkungen zu Ihrer Endpunktschnittstelle.

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) {
    }

}
Premraj
quelle
Ich verfolge das genau. Ich drucke die Nachricht aus, nachdem ich Änderungen am Header vorgenommen habe, sehe diese Änderungen jedoch nicht. Es sieht so aus, als würde sich die Nachricht erst ändern, nachdem sie die handleMessage-Methode verlassen hat
Iofacture
Wenn ich zweimal zum Drucken der Nachricht aufrufe, erfolgt das Update zum zweiten Mal. Sehr seltsam
Iofacture
11

Es gibt verschiedene Möglichkeiten, dies programmgesteuert zu tun, wie in den anderen Antworten beschrieben, aber es handelt sich um ziemlich invasive Mechanismen. Wenn Sie jedoch wissen, dass Sie JAX-WS RI (auch bekannt als "Metro") verwenden, können Sie dies auf Konfigurationsebene tun. Anweisungen dazu finden Sie hier. Sie müssen nicht mit Ihrer Anwendung herumspielen.

Skaffman
quelle
2
Metro = JAX-WS RI + WSIT (dh JAX-WS RI! = Metro)
Pascal Thivent
@Pau: Behoben. Sie wissen, anstatt mich dafür abzustimmen, hätten Sie sich ein wenig Mühe geben und einen alternativen Link vorschlagen können.
Skaffman
1
Wenn ich einen gefunden hätte, wäre ich sicher, dass ich ihn gestellt hätte. Nimm es nicht als persönlich. Abstimmung entfernt;)
Pau
Der Link ist wieder unterbrochen (was ist mit java.net los ???). Ich denke, das ist der neue Link: metro.java.net/nonav/1.2/guide/Logging.html
sdoca
9

// Diese Lösung bietet eine Möglichkeit, dem Webdienst-Clien ohne XML-Konfiguration programmgesteuert einen Handler hinzuzufügen

// Das vollständige Dokument finden Sie hier: http://docs.oracle.com/cd/E17904_01//web.1111/e13734/handlers.htm#i222476

// Neue Klasse erstellen, die SOAPHandler implementiert

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) {
}
}

// Fügen Sie Ihren LogMessageHandler programmgesteuert hinzu

   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);
TriMix
quelle
4

Ich poste eine neue Antwort, da ich nicht genug Ruf habe, um die von Antonio bereitgestellte zu kommentieren (siehe: https://stackoverflow.com/a/1957777 ).

Wenn Sie möchten, dass die SOAP-Nachricht in einer Datei gedruckt wird (z. B. über Log4j), können Sie Folgendes verwenden:

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

Bitte beachten Sie, dass sich der Methodenaufruf writeTo () unter bestimmten Umständen nicht wie erwartet verhält (siehe: https://community.oracle.com/thread/1123104?tstart=0 oder https://www.java.net/node) / 691073 ), daher reicht der folgende Code aus:

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());
Alex
quelle
2

Sie müssen einen javax.xml.ws.handler.LogicalHandler implementieren. Dieser Handler muss dann in einer Handler-Konfigurationsdatei referenziert werden, auf die wiederum durch eine @ HandlerChain-Annotation in Ihrem Service-Endpunkt (Schnittstelle oder Implementierung) verwiesen wird. Sie können die Nachricht dann entweder über system.out oder einen Logger in Ihrer processMessage-Implementierung ausgeben.

Sehen

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

stjohnroe
quelle
2

Die hier aufgeführten Antworten, die Sie verwenden sollen, SOAPHandlersind vollständig korrekt. Der Vorteil dieses Ansatzes besteht darin, dass er mit jeder JAX-WS-Implementierung funktioniert, da SOAPHandler Teil der JAX-WS-Spezifikation ist. Das Problem mit SOAPHandler besteht jedoch darin, dass implizit versucht wird, die gesamte XML-Nachricht im Speicher darzustellen. Dies kann zu einer enormen Speichernutzung führen. Verschiedene Implementierungen von JAX-WS haben hierfür eigene Problemumgehungen hinzugefügt. Wenn Sie mit großen Anfragen oder großen Antworten arbeiten, müssen Sie einen der proprietären Ansätze prüfen.

Da Sie nach "dem in JDK 1.5 oder besser enthaltenen" fragen, antworte ich in Bezug auf das, was formal als JAX-WS RI (auch bekannt als Metro) bekannt ist und was im JDK enthalten ist.

JAX-WS RI hat hierfür eine spezielle Lösung, die hinsichtlich der Speichernutzung sehr effizient ist.

Siehe https://javaee.github.io/metro/doc/user-guide/ch02.html#efficient-handlers-in-jax-ws-ri . Leider ist dieser Link jetzt defekt, aber Sie können ihn auf WayBack Machine finden. Ich werde die Highlights unten geben:

Die U - Bahn - Leute im Jahr 2007 eingeführt einen zusätzlichen Handler - Typen, MessageHandler<MessageHandlerContext>, die Metro proprietär ist. Es ist weitaus effizienter als SOAPHandler<SOAPMessageContext>die In-Memory-DOM-Darstellung.

Hier ist der entscheidende Text aus dem ursprünglichen Blog-Artikel:

MessageHandler:

Unter Verwendung des erweiterbaren Handler-Frameworks der JAX-WS-Spezifikation und der besseren Nachrichtenabstraktion in RI haben wir einen neuen Handler namens (eine Erweiterung von MessageContext) eingeführt. Über MessageHandlerContext kann auf die Nachricht zugegriffen und über die Nachrichten-API verarbeitet werden. Wie ich im Titel des Blogs angegeben habe, können Sie mit diesem Handler an Nachrichten arbeiten. Dies bietet effiziente Möglichkeiten, auf die Nachricht zuzugreifen / sie zu verarbeiten, nicht nur auf eine DOM-basierte Nachricht. Das Programmiermodell der Handler ist das gleiche und die Message-Handler können mit Standard-Logical- und SOAP-Handlern gemischt werden. Ich habe in JAX-WS RI 2.1.3 ein Beispiel hinzugefügt, das die Verwendung von MessageHandler zum Protokollieren von Nachrichten zeigt. Hier ist ein Ausschnitt aus dem Beispiel:MessageHandler zur Erweiterung Ihrer Webdienstanwendungen . MessageHandler ähnelt SOAPHandler, außer dass Implementierungen davon Zugriff erhaltenMessageHandlerContext

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

(Endzitat aus dem Blogbeitrag 2007)

Es ist unnötig zu erwähnen, dass Ihr benutzerdefinierter Handler LoggingHandlerim Beispiel zu Ihrer Handler-Kette hinzugefügt werden muss, um einen Effekt zu erzielen. Dies ist dasselbe wie das Hinzufügen eines anderen Handler. Sie können also in den anderen Antworten auf dieser Seite nachsehen, wie das geht.

Ein vollständiges Beispiel finden Sie im Metro GitHub-Repo .

Peterh
quelle
1

Sie können versuchen, eine ServletFiltervor den Webservice zu stellen und die Anforderung und Antwort zu überprüfen, die an den Service gesendet oder von diesem zurückgegeben wird.

Obwohl Sie ausdrücklich nicht nach einem Proxy gefragt haben, finde ich manchmal, dass tcptrace ausreicht, um zu sehen, was bei einer Verbindung vor sich geht. Es ist ein einfaches Tool, keine Installation, es zeigt die Datenströme an und kann auch in eine Datei schreiben.

rsp
quelle
1

Zur Laufzeit können Sie einfach ausführen

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

as dump ist eine öffentliche Variable, die in der Klasse wie folgt definiert ist

public static boolean dump;
jozh
quelle
Für mich arbeiten mit com.sun.xml.ws.transport.http.client.HttpTransportPipe.dump = true;
userfb
1

Habe ich Recht, wenn ich verstehe, dass Sie die unformatierte XML-Nachricht ändern / darauf zugreifen möchten?

In diesem Fall möchten Sie (oder da dies fünf Jahre alt ist, der nächste) möglicherweise einen Blick auf die Provider-Oberfläche werfen, die Teil von JAXWS ist. Das Client-Gegenstück wird mit der Klasse "Dispatch" erstellt. Auf jeden Fall müssen Sie keine Handler oder Interceptors hinzufügen. Das kannst du natürlich immer noch. Der Nachteil ist, dass Sie VOLLSTÄNDIG für die Erstellung der SOAPMessage verantwortlich sind, aber es ist einfach, und wenn Sie dies möchten (wie ich), ist dies perfekt.

Hier ist ein Beispiel für die Serverseite (etwas ungeschickt, es war nur zum Experimentieren) -

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


   }
}

Sie veröffentlichen es wie ein SEI,

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

Oder Sie können eine Endpoint-Klasse dafür verwenden. Hoffe das war hilfreich.

Und oh, wenn Sie möchten, müssen Sie sich nicht mit Headern und anderen Dingen befassen, wenn Sie den Servicemodus auf PAYLOAD ändern (Sie erhalten nur den Seifenkörper).

Aneesh Barthakur
quelle
1

Mit den Konfigurationsdateien logback.xml können Sie Folgendes tun:

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

Dadurch werden die Anforderung und die Antwort wie folgt protokolliert (abhängig von Ihrer Konfiguration für die Protokollausgabe):

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>--------------------
Christian Goudreau
quelle
1

Ich hatte einige Tage lang versucht, eine Framework-Bibliothek zu finden, um die Seifenanforderung und -antwort des Webdienstes zu protokollieren. Der folgende Code hat das Problem für mich behoben:

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");
JChanthamontry
quelle
0

Eine Möglichkeit besteht darin, nicht Ihren Code zu verwenden, sondern Netzwerkpaket-Sniffer wie Etheral oder WireShark zu verwenden, die das HTTP-Paket mit der XML-Nachricht als Nutzlast erfassen und sie weiterhin in einer Datei oder so protokollieren können.

Ein ausgefeilterer Ansatz besteht jedoch darin, eigene Nachrichtenhandler zu schreiben. Sie können es hier ansehen .

Shamik
quelle
0

Tatsächlich. Wenn Sie sich die Quellen von HttpClientTransport ansehen, werden Sie feststellen, dass auch Nachrichten in java.util.logging.Logger geschrieben werden. Das heißt, Sie können diese Nachrichten auch in Ihren Protokollen sehen.

Wenn Sie beispielsweise Log4J2 verwenden, müssen Sie lediglich Folgendes tun:

  • Fügen Sie die JUL-Log4J2-Brücke zu Ihrem Klassenpfad hinzu
  • Legen Sie die TRACE-Ebene für das Paket com.sun.xml.internal.ws.transport.http.client fest.
  • Fügen Sie -Djava.util.logging.manager = org.apache.logging.log4j.jul.LogManager-Systemeigenschaft zu Ihrer Anwendungsstart-Befehlszeile hinzu

Nach diesen Schritten werden SOAP-Nachrichten in Ihren Protokollen angezeigt.

Ruhm1
quelle
0

In diesem Thread gibt es einige Antworten mit SoapHandlers. Sie sollten wissen, dass SoapHandlers die Nachricht ändern, wenn sie writeTo(out)aufgerufen wird.

Durch Aufrufen der SOAPMessage- writeTo(out)Methode wird auch automatisch die saveChanges()Methode aufgerufen . Infolgedessen gehen alle angehängten MTOM / XOP-Binärdaten in einer Nachricht verloren.

Ich bin nicht sicher, warum dies geschieht, aber es scheint eine dokumentierte Funktion zu sein.

Darüber hinaus markiert diese Methode den Punkt, an dem die Daten aller AttachmentPart-Objekte in die Nachricht gezogen werden.

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

Mikko Tuominen
quelle
0

Wenn Sie zufällig einen IBM Liberty-App-Server ausführen , fügen Sie einfach ibm-ws-bnd.xml in das Verzeichnis WEB-INF ein.

<?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>
Mikko Tuominen
quelle