33

I want to log raw soap post requests if there are any errors , I am using JAX-WS. Any help will be appreciated.

Is there an easy way (aka: not using a proxy) to get access to the raw request/response XML for a webservice published with JAX-WS reference implementation (the one included in JDK 1.5 and better) only when exception occurs in response? I want to log raw SOAP reuest so that I can test it thorugh any webservice client at a later stage

8 Answers 8

36

Use

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

and

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

instead (note the "internal" in the package name), this did the trick for me.

Cheers, Torsten

Sign up to request clarification or add additional context in comments.

3 Comments

changed catalina.sh file , included 'internal' but still cant see any changes in logs/catalina.yyyy-MM-dd.log files
.internal. is required when you are using the JAX WS version contained in the JRE, whereas the non ".internal." version is used, when you are explicitly using a JAX WS library
how to add timestamp, at what time a particular request reached to server and at what time server responded back ?
31

Just thought I would mention this:

The question when to use the property name with the internal in it and when not ?

If you read the Metro Guide it will tell you to use:

on client:

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

on server:

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

However: It seems to me that when JAX-WS RI library got included as standard with the JDK (this was with Java 6) then Sun had to rename the property name to include 'internal'. So if you are using JAX-WS RI as it comes bundled with the JDK, then you must be sure to add the internal to the property name. Otherwise it will not work. In other words you need to use:

on client:

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

on server:

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

On the other hand if you are using a standalone version of JAX-WS RI (or of Metro as a whole) then I would guess you should use the property name without the internal.

I'll be glad if someone has inside knowledge on this and can say if this is true or not.

Comments

11

It is OK to go with system properties (here is Gradle DSL for test task):

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" 

but those settings are global and may have high volume to enable them on PROD... It is not fun to add filters to your logging framework bound to business logic if you want to reduce volume of XML logging.

Details on capturing req/rsp bodies in WS handlers are in my answer How can I pass data back from a SOAP handler to a webservice client?

Here is an important part:

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

To register handler and use preserved properties:

BindingProvider provider = (BindingProvider) port; List<Handler> handlerChain = provider.getBinding().getHandlerChain(); handlerChain.add(new MsgLogger()); provider.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); 

With this solution (it is only the skeleton, proper error handling / edge cases is up to you) you decide to log later when you've got response.

1 Comment

This answer is based on The Java API for XML-Based Web Services (JAX-WS) 2.3 spec so should work for any JAX WS implementation.
4

In addition to Torsten's answer

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

Make sure that you set this before instantiating the WebServiceClient object (the one that extends Service)

Comments

3

The first thing you might want to try is using one, or both, of the following system properties:

Client:

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

Server:

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

7 Comments

I added above properties in my catalina.properties file in my tomcat server, but cant see any logs updated, please advise
added to my catalina.sh on JAVA_OPTS but cant see any changes
Don't change catalina.properties. How are you setting JAVA_OPTS? The logging should be output via System.out.
Following is the JAVA_OPTS line in my catalina.sh file JAVA_OPTS="-Dcom.sun.xml.ws.fault.SOAPFaultBuilder.disableCaptureStackTrace = false -Djava.awt.headless=true -Dfile.encoding=UTF-8 -server -Xms512m -Xmx1024m -XX:NewSize=256m -XX:MaxNewSize=256m -XX:PermSize=256m -XX:MaxPermSize=256m -XX:+DisableExplicitGC -Dcom.sun.xml.ws.transport.http.client.HttpTransportPipe.dump = true -Dcom.sun.xml.ws.transport.http.HttpAdapter.dump = true"
...and nothing's showing up in logs/catalina.out? I suppose it would be good to know what JDK and Tomcat versions you're using...
|
2

If you working with Jboss 6.1 and you want to print the logs for the JAX-WS generated classes request to the SOAP web service, open the file /home/oracle/jboss-eap-6.1/bin/standalone.sh note: please go where you have installed jboss

You will find something like this

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

Change it to the one shown below

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" 

Also make sure you enable debug

DEBUG_MODE=true 

Comments

1

I think that what you need is an handler, see: http://jax-ws.java.net/articles/handlers_introduction.html
With handler you can intercept web service call, and have access to all the SOAP message.

Comments

1

This worked for me:

-Dcom.sun.xml.ws.transport.http.client.HttpTransportPipe.dump=true 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.