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
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
Je pensais juste mentionner ceci:
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.
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)
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
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.sh
note: 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
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.
Cela a fonctionné pour moi:
-Dcom.Sun.xml.ws.transport.http.client.HttpTransportPipe.dump=true
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.