Suivi des requêtes / réponses XML avec JAX-WS

172

Existe-t-il un moyen simple (alias: ne pas utiliser de proxy) pour accéder au XML de demande / réponse brute pour un service Web publié avec l'implémentation de référence JAX-WS (celle incluse dans JDK 1.5 et supérieur)? Être capable de le faire via le code est ce que je dois faire. Le simple fait de le connecter à un fichier par des configurations de journalisation intelligentes serait bien mais suffisant.

Je sais qu'il existe d'autres cadres plus complexes et complets qui pourraient faire cela, mais je voudrais que cela reste aussi simple que possible et axis, cxf, etc. ajoutent tous des frais généraux considérables que je veux éviter.

Merci!

Antonio
la source
5
Juste une note: JAX-WS est une norme, que CXF implémente.
Bozho
Définition des propriétés du système Java et des variables d'environnement voir: <br> stackoverflow.com/questions/7054972/…
Dafka

Réponses:

282

Les options suivantes activent la journalisation de toutes les communications avec la console (techniquement, vous n'en avez besoin que de l'une d'entre elles, mais cela dépend des bibliothèques que vous utilisez, donc la configuration des quatre est une option plus sûre). Vous pouvez le définir dans le code comme dans l'exemple, ou comme paramètre de ligne de commande en utilisant -D ou comme variable d'environnement comme Upendra l'a écrit.

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

Voir la question Traçage des requêtes / réponses XML avec JAX-WS en cas d'erreur pour plus de détails.

M. Napik
la source
7
Merci, c'est la meilleure réponse que j'ai trouvée à ce problème
M Smith
5
Cela ne fonctionne PAS pour moi, lorsque le CLIENT s'exécute dans Tomcat. Seul le truc -D fonctionne. Je crois que cela est dû à la structure classLoader dans Tomcat?
Rop
3
System.setProperty ("com.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.dump", "true"); est le bon pour JAX-WS 2.2 RI intégré dans JDK7 et utilisé par défaut
Glenn Bech
1
pour ce travail dans tomcat, vous devez ajouter ces commandes à JAVA_OPTS dans catalina.sh, par exemple sur la première ligne, ajoutez: 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 "après cela, vous pouvez vérifier catalina.out et la sortie de ceci s'affichera là.
Reece
4
Ajoutez également System.setProperty ("com.sun.xml.internal.ws.transport.http.HttpAdapter.dumpTreshold", "999999"); pour ne pas avoir la sortie de requête et de réponse tronquée
bits
84

Voici la solution en code brut (mise en place grâce à stjohnroe et Shamik):

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

Où SOAPLoggingHandler est (extrait d'exemples liés):

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
la source
8
Voir le lien si vous ne voyez toujours pas de réponse / demande xml avec le code ci-dessus: stackoverflow.com/questions/2808544/…
ian_scho
2
Cela repose sur l'existence d'un objet SOAPMessage, donc il échouera (il suffit d'imprimer une exception, mais pas la trace) si vous recevez une réponse mal formée du serveur. Vérifiez ma réponse, si vous avez besoin d'une trace même si les problèmes se passent.
M. Napik
Dans l'extrait en haut: concernant la dernière ligne ep.publish(publishURL);: qu'est-ce que c'est publishURL(dans mon code, l'url wsdl est incluse dans le service lui-même; je n'ai pas d'url à l'extérieur. Qu'est-ce que je manque?)
badera
Si vous souhaitez le publier sur toutes les interfaces, alors le publishUrl est quelque chose comme ceci (hltp = http): "hltp: //0.0.0.0: 8080 / standalone / service". Dans ce cas particulier, vous pouvez accéder au service à "hltp: //127.0.0.1: 8080 / standalone / service / yourService" où "yourService" est l'emplacement du port wsdl défini dans le wsdl.
riskop
@ Mr.Napik: Mais de cette façon, vous pouvez toujours fournir votre propre installation de journalisation, ce qui est bien lorsque vous utilisez un cadre de journalisation.
Daniel
54

Avant de démarrer tomcat, définissez JAVA_OPTScomme ci-dessous dans les environnements Linux. Puis démarrez Tomcat. Vous verrez la demande et la réponse dans le catalina.outfichier.

export JAVA_OPTS="$JAVA_OPTS -Dcom.sun.xml.ws.transport.http.client.HttpTransportPipe.dump=true"
Upendra
la source
3
Brillant. C'est la meilleure réponse à mon humble avis.
Pablo Santa Cruz
Pour une raison quelconque, pour moi c'est:-Dcom.sun.xml.ws.transport.http.client.HttpTransportPipe.dump=true
tibo
Pour une raison quelconque, cela n'a fonctionné que sur l'un de mes 3 services Web (j'ai 3 services Web JAX-WS dans mon application Web Tomcat). Une idée pourquoi cela ne fonctionnerait pas sur les 3?
David Brossard
Cela a bien fonctionné pour moi de voir pourquoi mon test a échoué (définissez l'option dans la `` configuration d'exécution '' de mon test comme `` argument VM '').
MrSmith42
Votre père vient d'exploiter Internet avec la meilleure réponse de tous les temps
vikingsteve
16

Définissez les propriétés système suivantes, cela activera la journalisation XML. Vous pouvez le définir dans java ou dans un fichier de configuration.

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

journaux de la console:

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
la source
14

Injecter SOAPHandlerdans l'interface du point final. nous pouvons tracer la demande et la réponse SOAP

Implémentation de SOAPHandler avec programmatique

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

Déclaratif en ajoutant une @HandlerChain(file = "handlers.xml")annotation à votre interface de point de terminaison.

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
la source
Je suis exactement cela. J'imprime le message après avoir apporté des modifications à l'en-tête, mais je ne vois pas ces changements. Il semble que le message ne change pas avant d'avoir quitté la méthode
handleMessage
Si j'appelle pour imprimer le message deux fois, la deuxième fois a la mise à jour. Très étrange
Iofacture
11

Il existe différentes façons de faire cela par programme, comme décrit dans les autres réponses, mais ce sont des mécanismes assez invasifs. Cependant, si vous savez que vous utilisez le JAX-WS RI (aka "Metro"), vous pouvez le faire au niveau de la configuration. Voir ici pour savoir comment procéder. Inutile de vous soucier de votre application.

skaffman
la source
2
Metro = JAX-WS RI + WSIT (ie JAX-WS RI! = Metro)
Pascal Thivent
@Pau: Corrigé. Vous savez, au lieu de me voter pour cela, vous auriez pu faire un peu d'effort et suggérer un lien alternatif.
skaffman
1
Si j'en avais trouvé un, soyez sûr que je l'aurais mis. Ne le prenez pas pour personnel. supprimé vote vers le bas;)
Pau
Le lien est à nouveau rompu (qu'est-ce qui se passe avec java.net ???). Je pense que c'est le nouveau lien: metro.java.net/nonav/1.2/guide/Logging.html
sdoca
9

// Cette solution fournit un moyen d'ajouter par programme un gestionnaire au client du service Web sans la configuration XML

// Voir la documentation complète ici: http://docs.oracle.com/cd/E17904_01//web.1111/e13734/handlers.htm#i222476

// Créer une nouvelle classe qui implémente 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) {
}
}

// Ajoutez votre LogMessageHandler par programme

   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
la source
4

Je poste une nouvelle réponse, car je n'ai pas assez de réputation pour commenter celle fournie par Antonio (voir: https://stackoverflow.com/a/1957777 ).

Si vous souhaitez que le message SOAP soit imprimé dans un fichier (par exemple via Log4j), vous pouvez utiliser:

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

Veuillez noter que dans certaines circonstances, l'appel de méthode writeTo () peut ne pas se comporter comme prévu (voir: https://community.oracle.com/thread/1123104?tstart=0 ou https://www.java.net/node / 691073 ), donc le code suivant fera l'affaire:

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
la source
2

Vous devez implémenter un javax.xml.ws.handler.LogicalHandler, ce gestionnaire doit ensuite être référencé dans un fichier de configuration de gestionnaire, qui à son tour est référencé par une annotation @HandlerChain dans votre point de terminaison de service (interface ou implémentation). Vous pouvez ensuite afficher le message via system.out ou un enregistreur dans votre implémentation processMessage.

Voir

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
la source
2

Les réponses énumérées ici qui vous guident à utiliser SOAPHandlersont tout à fait correctes. L'avantage de cette approche est qu'elle fonctionnera avec n'importe quelle implémentation JAX-WS, car SOAPHandler fait partie de la spécification JAX-WS. Cependant, le problème avec SOAPHandler est qu'il tente implicitement de représenter l'ensemble du message XML en mémoire. Cela peut entraîner une énorme utilisation de la mémoire. Diverses implémentations de JAX-WS ont ajouté leurs propres solutions de contournement pour cela. Si vous travaillez avec des demandes volumineuses ou des réponses volumineuses, vous devez vous pencher sur l'une des approches propriétaires.

Puisque vous posez des questions sur "celui inclus dans JDK 1.5 ou mieux", je répondrai en ce qui concerne ce qui est officiellement connu sous le nom de JAX-WS RI (alias Metro) qui est ce qui est inclus avec le JDK.

JAX-WS RI a pour cela une solution spécifique qui est très efficace en termes d'utilisation de la mémoire.

Voir https://javaee.github.io/metro/doc/user-guide/ch02.html#efficient-handlers-in-jax-ws-ri . Malheureusement, ce lien est maintenant rompu mais vous pouvez le trouver sur WayBack Machine. Je vais vous donner les faits saillants ci-dessous:

Les gens de Metro en 2007 ont introduit un type de gestionnaire supplémentaire MessageHandler<MessageHandlerContext>, qui est la propriété de Metro. C'est beaucoup plus efficace que SOAPHandler<SOAPMessageContext>de ne pas essayer de faire une représentation DOM en mémoire.

Voici le texte crucial de l'article original du blog:

MessageHandler:

En utilisant le framework extensible Handler fourni par JAX-WS Specification et la meilleure abstraction de Message dans RI, nous avons introduit un nouveau gestionnaire appeléMessageHandler pour étendre vos applications de service Web. MessageHandler est similaire à SOAPHandler, sauf que ses implémentations ont accès àMessageHandlerContext(une extension de MessageContext). Grâce à MessageHandlerContext, on peut accéder au Message et le traiter à l'aide de l'API Message. Comme je l'ai indiqué dans le titre du blog, ce gestionnaire vous permet de travailler sur Message, qui fournit des moyens efficaces d'accéder / traiter le message et pas seulement un message basé sur DOM. Le modèle de programmation des gestionnaires est le même et les gestionnaires de messages peuvent être mélangés avec les gestionnaires standard Logical et SOAP. J'ai ajouté un exemple dans JAX-WS RI 2.1.3 montrant l'utilisation de MessageHandler pour consigner les messages et voici un extrait de l'exemple:

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

(citation de fin du billet de blog 2007)

Inutile de dire que votre gestionnaire personnalisé, LoggingHandlerdans l'exemple, doit être ajouté à votre chaîne de gestionnaire pour avoir un effet. C'est la même chose que l'ajout de tout autre Handler, vous pouvez donc regarder dans les autres réponses sur cette page pour savoir comment faire cela.

Vous pouvez trouver un exemple complet dans le repo Metro GitHub .

Peterh
la source
1

Vous pouvez essayer de mettre un ServletFilterdevant le service Web et d'inspecter la demande et la réponse envoyées / renvoyées par le service.

Bien que vous n'ayez spécifiquement pas demandé de proxy, je trouve parfois que tcptrace est suffisant pour voir ce qui se passe sur une connexion. C'est un outil simple, pas d'installation, il affiche les flux de données et peut également écrire dans un fichier.

rsp
la source
1

Au runtime, vous pouvez simplement exécuter

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

as dump est une variable publique définie dans la classe comme suit

public static boolean dump;
jozh
la source
Pour moi, travaillez avec com.sun.xml.ws.transport.http.client.HttpTransportPipe.dump = true;
userfb
1

ai-je raison de comprendre que vous souhaitez modifier / accéder au message XML brut?

Si tel est le cas, vous (ou depuis l'âge de cinq ans, le prochain) voudrez peut-être jeter un coup d'œil à l'interface du fournisseur qui fait partie de JAXWS. La contrepartie client se fait à l'aide de la classe "Dispatch". Quoi qu'il en soit, vous n'avez pas besoin d'ajouter de gestionnaires ou d'intercepteurs. Vous pouvez toujours, bien sûr. L'inconvénient est que vous êtes COMPLÈTEMENT responsable de la construction du SOAPMessage, mais c'est facile, et si c'est ce que vous voulez (comme je l'ai fait), c'est parfait.

Voici un exemple pour le côté serveur (un peu maladroit, c'était juste pour expérimenter) -

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


   }
}

Vous le publiez comme un 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);
}
}

Ou vous pouvez utiliser une classe Endpoint pour cela. J'espère que cela a été utile.

Et oh, si vous voulez, vous n'avez pas besoin de gérer les en-têtes et autres choses, si vous changez le mode de service sur PAYLOAD (vous n'obtiendrez que le corps de savon).

Aneesh Barthakur
la source
1

avec les fichiers de configuration logback.xml, vous pouvez faire:

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

Cela enregistrera la demande et la réponse comme ceci (en fonction de votre configuration pour la sortie du journal):

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
la source
1

J'avais essayé de trouver une bibliothèque de cadres pour enregistrer la demande et la réponse de savon du service Web pendant quelques jours. Le code ci-dessous a résolu le problème pour moi:

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
la source
0

Une façon de faire consiste à ne pas utiliser votre code mais à utiliser des renifleurs de paquets réseau comme Etheral ou WireShark qui peuvent capturer le paquet HTTP avec le message XML comme charge utile et vous pouvez continuer à les enregistrer dans un fichier ou plus.

Mais une approche plus sophistiquée consiste à écrire vos propres gestionnaires de messages. Vous pouvez le consulter ici .

Shamik
la source
0

Réellement. Si vous regardez dans les sources de HttpClientTransport, vous remarquerez qu'il écrit également des messages dans java.util.logging.Logger. Ce qui signifie que vous pouvez également voir ces messages dans vos journaux.

Par exemple, si vous utilisez Log4J2, tout ce que vous avez à faire est ce qui suit:

  • ajoutez le pont JUL-Log4J2 dans votre chemin de classe
  • définir le niveau TRACE pour le package com.sun.xml.internal.ws.transport.http.client.
  • ajoutez la propriété système -Djava.util.logging.manager = org.apache.logging.log4j.jul.LogManager à votre ligne de commande de démarrage d'application

Après ces étapes, vous commencez à voir les messages SOAP dans vos journaux.

gloire1
la source
0

Il y a quelques réponses à l'aide de SoapHandlers dans ce fil. Vous devez savoir que SoapHandlers modifie le message s'il writeTo(out)est appelé.

L'appel de la writeTo(out)méthode SOAPMessage appelle également la méthode automatiquement saveChanges(). En conséquence, toutes les données binaires MTOM / XOP attachées dans un message sont perdues.

Je ne sais pas pourquoi cela se produit, mais cela semble être une fonctionnalité documentée.

En outre, cette méthode marque le point auquel les données de tous les objets AttachmentPart constitutifs sont extraites dans le message.

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

Mikko Tuominen
la source
0

Si vous exécutez un serveur d'applications IBM Liberty, ajoutez simplement ibm-ws-bnd.xml dans le répertoire 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
la source