Śledzenie żądań / odpowiedzi XML za pomocą JAX-WS

172

Czy istnieje łatwy sposób (inaczej: nie używanie proxy), aby uzyskać dostęp do surowego XML żądania / odpowiedzi dla usługi internetowej opublikowanej z implementacją referencyjną JAX-WS (tę zawartą w JDK 1.5 i nowszych)? Muszę to zrobić za pomocą kodu. Samo zalogowanie go do pliku za pomocą sprytnych konfiguracji logowania byłoby fajne, ale wystarczające.

Wiem, że istnieją inne, bardziej złożone i kompletne frameworki, które mogą to zrobić, ale chciałbym, aby było to tak proste, jak to tylko możliwe, a axis, cxf itp. Dodają znaczny narzut, którego chcę uniknąć.

Dzięki!

Antonio
źródło
5
Uwaga: JAX-WS to standard, który implementuje CXF.
Bozho
Ustawianie właściwości systemu Java i zmiennych środowiskowych patrz: <br> stackoverflow.com/questions/7054972/ ...
Dafka

Odpowiedzi:

282

Poniższe opcje umożliwiają rejestrowanie całej komunikacji z konsolą (technicznie potrzebujesz tylko jednej z nich, ale zależy to od używanych bibliotek, więc ustawienie wszystkich czterech jest bezpieczniejszą opcją). Możesz ustawić go w kodzie, jak w przykładzie, lub jako parametr wiersza poleceń za pomocą -D lub jako zmienną środowiskową, jak napisała Upendra.

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

Szczegółowe informacje można znaleźć w pytaniu Śledzenie żądań / odpowiedzi XML za pomocą JAX-WS w przypadku wystąpienia błędu .

Panie Napik
źródło
7
Dzięki, to najlepsza odpowiedź, jaką znalazłem na ten problem
M Smith
5
To NIE działa dla mnie, gdy KLIENT działa w Tomcat. Działa tylko opcja -D. Uważam, że jest to spowodowane strukturą classLoader w Tomcat?
Rop
3
System.setProperty ("com.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.dump", "true"); jest właściwym dla JAX-WS 2.2 RI dołączonym do JDK7 i używanym domyślnie
Glenn Bech
1
do tej pracy w tomcat trzeba dodać te polecenia do JAVA_OPTS w catalina.sh, np. w pierwszej linii dodaj: 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 "po tym możesz sprawdzić catalina.out, a dane wyjściowe z tego zostaną wyświetlone.
Reece,
4
Dodaj również System.setProperty ("com.sun.xml.internal.ws.transport.http.HttpAdapter.dumpTreshold", "999999"); aby nie
obcinano
84

Oto rozwiązanie w surowym kodzie (zebrane dzięki stjohnroe i Shamik):

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

Gdzie SOAPLoggingHandler jest (zgrany z połączonych przykładów):

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
źródło
8
Zobacz link, jeśli nadal nie widzisz kodu XML odpowiedzi / żądania z powyższym kodem: stackoverflow.com/questions/2808544/…
ian_scho
2
Zależy to od istnienia obiektu SOAPMessage, więc zakończy się niepowodzeniem (po prostu wydrukuje wyjątek, ale nie ślad), jeśli otrzymasz zniekształconą odpowiedź z serwera. Sprawdź moją odpowiedź, jeśli potrzebujesz śladu, nawet jeśli coś pójdzie nie tak.
Pan Napik
We fragmencie u góry: dotyczy ostatniej linii ep.publish(publishURL);: co to jest publishURL(w moim kodzie adres URL wsdl jest zawarty w samej usłudze; nie mam żadnego adresu na zewnątrz. Czego brakuje?)
badera
Jeśli chcesz opublikować go na wszystkich interfejsach, to PublishingUrl wygląda następująco (hltp = http): "hltp: //0.0.0.0: 8080 / standalone / service". W tym konkretnym przypadku dostęp do usługi można uzyskać pod adresem „hltp: //127.0.0.1: 8080 / standalone / service / yourService”, gdzie „yourService” to lokalizacja portu wsdl zdefiniowana w pliku wsdl.
riskop
@ Mr.Napik: Ale w ten sposób nadal możesz zapewnić własne narzędzie do logowania, co jest przyjemne, gdy używasz struktury rejestrowania.
Daniel
54

Przed uruchomieniem tomcat ustaw JAVA_OPTSjak poniżej w środowisku Linux. Następnie uruchom Tomcat. W catalina.outpliku zobaczysz żądanie i odpowiedź .

export JAVA_OPTS="$JAVA_OPTS -Dcom.sun.xml.ws.transport.http.client.HttpTransportPipe.dump=true"
Upendra
źródło
3
Znakomity. To najlepsza odpowiedź IMHO.
Pablo Santa Cruz
Z jakiegoś powodu jest to dla mnie:-Dcom.sun.xml.ws.transport.http.client.HttpTransportPipe.dump=true
tibo
Z jakiegoś powodu zadziałało to tylko na jednej z moich 3 usług sieciowych (mam 3 usługi sieciowe JAX-WS w mojej aplikacji internetowej Tomcat). Masz jakiś pomysł, dlaczego to nie zadziała na wszystkich 3?
David Brossard
Pomogło mi, aby zobaczyć, dlaczego mój test się nie powiódł (ustaw opcję w „uruchom konfigurację” mojego testu jako „argument maszyny wirtualnej”).
MrSmith42
Twój ojciec właśnie wykorzystał internet, udzielając najlepszej odpowiedzi
vikingsteve
16

Ustaw następujące właściwości systemu, spowoduje to włączenie rejestrowania XML. Możesz to ustawić w javie lub pliku konfiguracyjnym.

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

dzienniki konsoli:

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
źródło
14

Wstrzyknij SOAPHandlerdo interfejsu punktu końcowego. możemy śledzić żądanie i odpowiedź SOAP

Implementowanie SOAPHandler z Programmatic

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

Deklaratywne , dodając @HandlerChain(file = "handlers.xml")adnotację do interfejsu punktu końcowego.

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
źródło
Dokładnie to podążam. Drukuję wiadomość po wprowadzeniu zmian w nagłówku, ale nie widzę tych zmian. Wygląda na to, że wiadomość nie zmienia się, dopóki nie opuści metody
handleMessage
Jeśli dwukrotnie wezwę wydrukowanie wiadomości, za drugim razem mam aktualizację. Bardzo dziwne
Iofacture
11

Istnieją różne sposoby wykonywania tego programowo, jak opisano w innych odpowiedziach, ale są to dość inwazyjne mechanizmy. Jeśli jednak wiesz, że używasz JAX-WS RI (aka „Metro”), możesz to zrobić na poziomie konfiguracji. Zobacz tutaj, aby uzyskać instrukcje, jak to zrobić. Nie musisz martwić się swoją aplikacją.

skaffman
źródło
2
Metro = JAX-WS RI + WSIT (tj. JAX-WS RI! = Metro)
Pascal Thivent,
@Pau: Naprawiono. Wiesz, zamiast głosować na mnie za to, mogłeś włożyć trochę wysiłku i zasugerować alternatywny link.
skaffman
1
Gdybym znalazł, na pewno bym go umieścił. Nie traktuj tego jako osobistego. usunięto głosowanie w dół;)
Pau
Link znowu jest uszkodzony (o co chodzi z java.net ???). Myślę, że to nowy link: metro.java.net/nonav/1.2/guide/Logging.html
sdoca
9

// To rozwiązanie umożliwia programowe dodawanie modułu obsługi do klienta usługi sieciowej bez konfiguracji XML

// Zobacz pełną dokumentację tutaj: http://docs.oracle.com/cd/E17904_01//web.1111/e13734/handlers.htm#i222476

// Utwórz nową klasę, która implementuje 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) {
}
}

// Programowo dodaj swój 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);
TriMix
źródło
4

Piszę nową odpowiedź, ponieważ nie mam wystarczającej reputacji, aby skomentować tę dostarczoną przez Antonio (patrz: https://stackoverflow.com/a/1957777 ).

W przypadku, gdy chcesz, aby wiadomość SOAP została wydrukowana w pliku (np. Przez Log4j), możesz użyć:

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

Należy pamiętać, że w pewnych okolicznościach wywołanie metody writeTo () może nie działać zgodnie z oczekiwaniami (patrz: https://community.oracle.com/thread/1123104?tstart=0 lub https://www.java.net/node / 691073 ), dlatego poniższy kod załatwi sprawę :

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
źródło
2

Musisz zaimplementować javax.xml.ws.handler.LogicalHandler, ten program obsługi musi następnie zostać przywołany w pliku konfiguracyjnym programu obsługi, do którego z kolei odwołuje się adnotacja @HandlerChain w punkcie końcowym usługi (interfejsie lub implementacji). Następnie możesz wysłać wiadomość przez system.out lub rejestrator w implementacji processMessage.

Widzieć

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
źródło
2

Odpowiedzi wymienione tutaj, które prowadzą do użycia, SOAPHandlersą w pełni poprawne. Zaletą tego podejścia jest to, że będzie działać z każdą implementacją JAX-WS, ponieważ SOAPHandler jest częścią specyfikacji JAX-WS. Jednak problem z SOAPHandler polega na tym, że niejawnie próbuje przedstawić całą wiadomość XML w pamięci. Może to prowadzić do ogromnego zużycia pamięci. Różne implementacje JAX-WS dodały własne obejścia tego problemu. Jeśli pracujesz z dużymi żądaniami lub dużymi odpowiedziami, musisz przyjrzeć się jednemu z zastrzeżonych podejść.

Ponieważ pytasz o „ten zawarty w JDK 1.5 lub lepszy”, odpowiem w odniesieniu do tego, co jest formalnie znane jako JAX-WS RI (aka Metro), które jest zawarte w JDK.

JAX-WS RI ma na to specyficzne rozwiązanie, które jest bardzo wydajne pod względem wykorzystania pamięci.

Zobacz https://javaee.github.io/metro/doc/user-guide/ch02.html#efficient-handlers-in-jax-ws-ri . Niestety ten link jest teraz uszkodzony, ale możesz go znaleźć w WayBack Machine. Poniżej podam najważniejsze informacje:

Ludzie z Metro w 2007 roku wprowadzili dodatkowy typ obsługi MessageHandler<MessageHandlerContext>, który jest własnością Metro. Jest o wiele bardziej wydajne niż SOAPHandler<SOAPMessageContext>to, że nie próbuje wykonywać reprezentacji DOM w pamięci.

Oto kluczowy tekst z oryginalnego artykułu na blogu:

MessageHandler:

Wykorzystując rozszerzalną strukturę Handler dostarczoną przez specyfikację JAX-WS Specification i lepszą abstrakcję komunikatów w RI, wprowadziliśmy nową procedurę obsługi wywoływaną w MessageHandlercelu rozszerzenia aplikacji Web Service. MessageHandler jest podobny do SOAPHandler, z wyjątkiem tego, że jego implementacje mają dostęp doMessageHandlerContext(rozszerzenie MessageContext). Poprzez MessageHandlerContext można uzyskać dostęp do Message i przetworzyć go za pomocą Message API. Jak umieściłem w tytule bloga, ten program obsługi pozwala ci pracować nad Message, który zapewnia efektywne sposoby dostępu / przetwarzania wiadomości, a nie tylko wiadomości opartej na DOM. Model programowania procedur obsługi jest taki sam, a programy obsługi komunikatów można mieszać ze standardowymi programami obsługi logicznej i SOAP. Dodałem przykład w JAX-WS RI 2.1.3 pokazujący użycie MessageHandler do rejestrowania komunikatów, a oto fragment z przykładu:

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

(końcowy cytat z wpisu na blogu z 2007 roku)

Nie trzeba dodawać, że niestandardowy Handler, LoggingHandlerw tym przykładzie, musi zostać dodany do łańcucha Handler Chain, aby miał jakikolwiek efekt. To jest to samo, co dodawanie innych Handler, więc możesz zajrzeć do innych odpowiedzi na tej stronie, aby dowiedzieć się, jak to zrobić.

Możesz znaleźć pełny przykład w repozytorium Metro GitHub .

peterh
źródło
1

Możesz spróbować umieścić ServletFilterprzed usługą sieciową i sprawdzić żądanie i odpowiedź przychodzące / zwracane z usługi.

Chociaż specjalnie nie prosiłeś o proxy, czasami uważam, że tcptrace wystarczy, aby zobaczyć, co się dzieje w połączeniu. To proste narzędzie, bez instalacji, pokazuje strumienie danych i może również zapisywać do pliku.

rsp
źródło
1

W czasie wykonywania możesz po prostu wykonać

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

ponieważ zrzut jest publiczną zmienną zdefiniowaną w klasie w następujący sposób

public static boolean dump;
jozh
źródło
Jak dla mnie praca z com.sun.xml.ws.transport.http.client.HttpTransportPipe.dump = true;
userfb
1

czy mam rację rozumiejąc, że chcesz zmienić / uzyskać dostęp do nieprzetworzonej wiadomości XML?

Jeśli tak, Ty (lub następny facet, ponieważ ma pięć lat) możesz rzucić okiem na interfejs dostawcy, który jest częścią JAXWS. Odpowiednik klienta jest wykonywany przy użyciu klasy „Wysyłka”. W każdym razie nie musisz dodawać obsługi ani przechwytywaczy. Oczywiście nadal MOŻESZ. Wadą jest to, że jesteś CAŁKOWICIE odpowiedzialny za zbudowanie SOAPMessage, ale jest to łatwe, a jeśli tego chcesz (tak jak ja), jest to idealne.

Oto przykład po stronie serwera (trochę niezdarny, służył tylko do eksperymentowania) -

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


   }
}

Publikujesz to tak, jakbyś był 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);
}
}

Możesz też użyć do tego klasy Endpoint. Mam nadzieję, że to było pomocne.

I och, jeśli chcesz, nie musisz zajmować się nagłówkami i innymi rzeczami, jeśli zmienisz tryb usługi na PAYLOAD (dostaniesz tylko Soap Body).

Aneesh Barthakur
źródło
1

za pomocą plików konfiguracyjnych logback.xml możesz:

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

Spowoduje to zarejestrowanie żądania i takiej odpowiedzi (w zależności od konfiguracji danych wyjściowych dziennika):

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
źródło
1

Przez kilka dni próbowałem znaleźć bibliotekę ramową do rejestrowania żądania mydła usługi sieciowej i odpowiedzi. Poniższy kod rozwiązał problem:

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
źródło
0

Jednym ze sposobów jest nieużywanie kodu, ale używanie snifferów pakietów sieciowych, takich jak Etheral lub WireShark, które mogą przechwytywać pakiet HTTP z komunikatem XML jako ładunkiem do niego i możesz nadal rejestrować je w pliku lub tak dalej.

Ale bardziej wyrafinowanym podejściem jest napisanie własnych programów obsługi wiadomości. Możesz go zobaczyć tutaj .

Shamik
źródło
0

Tak właściwie. Jeśli spojrzysz na źródła HttpClientTransport, zauważysz, że zapisuje on również wiadomości w java.util.logging.Logger. Co oznacza, że ​​możesz zobaczyć te wiadomości również w swoich dziennikach.

Na przykład, jeśli używasz Log4J2, wszystko, co musisz zrobić, to:

  • dodaj most JUL-Log4J2 do ścieżki klasy
  • ustawić poziom TRACE dla pakietu com.sun.xml.internal.ws.transport.http.client.
  • dodaj właściwość systemową -Djava.util.logging.manager = org.apache.logging.log4j.jul.LogManager do wiersza poleceń uruchamiania aplikacji

Po wykonaniu tych czynności w dziennikach zaczniesz widzieć komunikaty SOAP.

chwała 1
źródło
0

W tym wątku jest kilka odpowiedzi za pomocą SoapHandlers. Powinieneś wiedzieć, że SoapHandlers modyfikują wiadomość, jeśli writeTo(out)zostanie wywołana.

Wywołanie writeTo(out)metody SOAPMessage automatycznie wywołuje saveChanges()również metodę. W rezultacie wszystkie dołączone dane binarne MTOM / XOP w wiadomości zostaną utracone.

Nie jestem pewien, dlaczego tak się dzieje, ale wydaje się, że jest to udokumentowana funkcja.

Ponadto metoda ta oznacza punkt, w którym dane ze wszystkich składowych obiektów AttachmentPart są pobierane do wiadomości.

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

Mikko Tuominen
źródło
0

Jeśli zdarzy ci się uruchomić serwer aplikacji IBM Liberty, po prostu dodaj ibm-ws-bnd.xml do katalogu 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>
Mikko Tuominen
źródło