web-dev-qa-db-fra.com

Suivi des demandes / réponses XML avec JAX-WS en cas d'erreur

Je souhaite enregistrer les demandes de publication de savon brutes s'il y a des erreurs, j'utilise JAX-WS. Toute aide serait appréciée.

Existe-t-il un moyen simple (alias: ne pas utiliser de proxy) d'accéder au XML brut de demande/réponse pour un service Web publié avec l'implémentation de référence JAX-WS (celui inclus dans JDK 1.5 et supérieur) uniquement lorsqu'une exception se produit en réponse? Je veux me connecter raw SOAP reuest afin de pouvoir le tester à travers n'importe quel client de service Web à un stade ultérieur

24
user665837

Utilisation

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

et

com.Sun.xml.internal.ws.transport.http.HttpAdapter.dump=true

à la place (notez le "interne" dans le nom du package), cela a fait l'affaire pour moi.

À la vôtre, Torsten

33
Torsten

Je pensais juste mentionner ceci:

La question quand utiliser le nom de la propriété avec le internal dedans et quand non?

Si vous lisez Metro Guide il vous dira d'utiliser:

sur le client:

com.Sun.xml.ws.transport.http.client.HttpTransportPipe.dump=true

sur le serveur:

com.Sun.xml.ws.transport.http.HttpAdapter.dump=true

Cependant: il me semble que lorsque la bibliothèque JAX-WS RI a été incluse en standard avec le JDK (c'était avec Java 6), Sun a dû renommer le nom de la propriété pour inclure `` interne ''). Donc, si vous utilisez JAX-WS RI tel qu'il est fourni avec le JDK, vous devez être sûr d'ajouter le internal à le nom de la propriété. Sinon, cela ne fonctionnera pas. En d'autres termes, vous devez utiliser:

sur le client:

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

sur le serveur:

com.Sun.xml.internal.ws.transport.http.HttpAdapter.dump=true

D'un autre côté, si vous utilisez une version autonome de JAX-WS RI (ou de Metro dans son ensemble), je suppose que vous devriez utiliser le nom de la propriété sans le internal.

Je serai heureux si quelqu'un a des connaissances internes à ce sujet et peut dire si cela est vrai ou non.

27
peterh

En plus de la réponse de Torsten

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

Assurez-vous de le définir avant d'instancier l'objet WebServiceClient (celui qui étend le service)

4
thirdy

La première chose que vous voudrez peut-être essayer est d'utiliser l'une des propriétés système suivantes, ou les deux:

Client:

com.Sun.xml.ws.transport.http.client.HttpTransportPipe.dump=true

Serveur:

com.Sun.xml.ws.transport.http.HttpAdapter.dump=true
3
kschneid

Si vous travaillez avec Jboss 6.1 et que vous souhaitez imprimer les journaux de la demande de classes générées par JAX-WS sur le service Web SOAP, ouvrez le fichier /home/Oracle/jboss-eap-6.1/bin/standalone.shnote: veuillez aller là où vous avez installé jboss

Vous trouverez quelque chose comme ça

Java_OPTS="$Java_OPTS -agentlib:jdwp=transport=dt_socket,address=$DEBUG_PORT,server=y,suspend=n"

Remplacez-le par celui illustré ci-dessous

Java_OPTS="$Java_OPTS -Dcom.Sun.xml.ws.transport.http.client.HttpTransportPipe.dump=true -agentlib:jdwp=transport=dt_socket,address=$DEBUG_PORT,server=y,suspend=n"

Assurez-vous également d'activer le débogage

DEBUG_MODE=true
2
vinodh nair

Il est correct d'utiliser les propriétés du système (voici Gradle DSL pour la tâche test):

systemProperty "com.Sun.xml.ws.transport.http.client.HttpTransportPipe.dump", "true"
systemProperty "com.Sun.xml.internal.ws.transport.http.client.HttpTransportPipe.dump", "true"
systemProperty "com.Sun.xml.ws.transport.http.HttpAdapter.dump", "true"
systemProperty "com.Sun.xml.internal.ws.transport.http.HttpAdapter.dump", "true"
systemProperty "com.Sun.xml.ws.transport.http.HttpAdapter.dumpTreshold", "99999"
systemProperty "com.Sun.xml.internal.ws.transport.http.HttpAdapter.dumpTreshold", "99999"

mais ces paramètres sont globaux et peuvent avoir un volume élevé pour les activer sur PROD ... Ce n'est pas amusant d'ajouter des filtres à votre infrastructure de journalisation liés à la logique métier si vous souhaitez réduire le volume de journalisation XML.

Les détails sur la capture des corps req/rsp dans les gestionnaires WS sont dans ma réponse Comment puis-je transmettre des données d'un gestionnaire SOAP à un client de service Web?

Voici une partie importante:

public class MsgLogger implements SOAPHandler<SOAPMessageContext> {

    public static String REQEST_BODY = "com.evil.request";
    public static String RESPONSE_BODY = "com.evil.response";

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

    @Override
    public boolean handleMessage(SOAPMessageContext context) {
        SOAPMessage msg = context.getMessage();
        Boolean beforeRequest = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream(32_000);
            context.getMessage().writeTo(baos);
            String key = beforeRequest ? REQEST_BODY : RESPONSE_BODY;
            context.put(key, baos.toString("UTF-8"));
            context.setScope(key, MessageContext.Scope.APPLICATION);
        } catch (SOAPException | IOException e) { }
        return true;
    }

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

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

Pour enregistrer le gestionnaire et utiliser les propriétés préservées:

BindingProvider provider = (BindingProvider) port;
List<Handler> handlerChain = bindingProvider.getBinding().getHandlerChain();
handlerChain.add(new MsgLogger());
bindingProvider.getBinding().setHandlerChain(handlerChain);

Req req = ...;
Rsp rsp = port.serviceCall(req); // call WS Port

// Access saved message bodies:
Map<String, Object> responseContext = provider.getResponseContext();
String reqBody = (String) responseContext.get(MsgLogger.REQEST_BODY);
String rspBody = (String) responseContext.get(MsgLogger.RESPONSE_BODY);

Avec cette solution (ce n'est que le squelette, la gestion des erreurs/les cas Edge dépend de vous), vous décidez de vous connecter plus tard lorsque vous aurez la réponse.

2
gavenkoa

Cela a fonctionné pour moi:

-Dcom.Sun.xml.ws.transport.http.client.HttpTransportPipe.dump=true
1
Wojtek

Je pense que ce dont vous avez besoin est un gestionnaire, voir: http://jax-ws.Java.net/articles/handlers_introduction.html
Avec le gestionnaire, vous pouvez intercepter les appels de service Web et avoir accès à tous les messages SOAP.

1
lpinto.eu