'How can I make Spring WebServices log all SOAP requests?
I need all SOAP requests logged in the CommonLogFormat
(see http://en.wikipedia.org/wiki/Common_Log_Format), plus the duration (the amount of time it takes to process the request).
What's the best way to do this? It looks like it's possible to configure log4j for Spring WebServices but will it log all the values I'm interested in? http://pijava.wordpress.com/2009/12/04/spring-webservice-soap-requestresponse-logging-with-log4j/
EDIT: We're actually using SLF4J
, not Log4j
. Also, it looks like it's possible to do this by configuring the PayloadLoggingInterceptor:
http://static.springsource.org/spring-ws/site/reference/html/server.html#server-endpoint-interceptor
But I am not sure where the log messages will go. I added that interceptor to our interceptors and I don't see any log messages.
Solution 1:[1]
For Spring Boot project adding below in application.properties
worked for me:
logging.level.org.springframework.web=DEBUG
logging.level.org.springframework.ws.client.MessageTracing.sent=DEBUG
logging.level.org.springframework.ws.server.MessageTracing.sent=DEBUG
logging.level.org.springframework.ws.client.MessageTracing.received=TRACE
logging.level.org.springframework.ws.server.MessageTracing.received=TRACE
Solution 2:[2]
You can use this to log the raw paylod of incoming and outgoing web service calls.. I'm not sure how to log how long the webservice communication took.
<!-- Spring Web Service Payload Logging-->
<logger name="org.springframework.ws.client.MessageTracing">
<level value="TRACE"/>
</logger>
<logger name="org.springframework.ws.server.MessageTracing">
<level value="TRACE"/>
</logger>
Additional details can be found at http://static.springsource.org/spring-ws/site/reference/html/common.html#logging
Solution 3:[3]
This worked for me. It logs the request message sent and the response received. You could work out the total time taken from the log.
log4j.logger.org.springframework.ws.client.MessageTracing.sent=TRACE
log4j.logger.org.springframework.ws.client.MessageTracing.received=TRACE
Solution 4:[4]
If you have your own Logging system the following interceptor can be an alternative to log the SOAP messages.
setInterceptors(new ClientInterceptor[]{new ClientInterceptor() {
@Override
public boolean handleResponse(MessageContext messageContext) throws WebServiceClientException {
System.out.println("### SOAP RESPONSE ###");
try {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
messageContext.getResponse().writeTo(buffer);
String payload = buffer.toString(java.nio.charset.StandardCharsets.UTF_8.name());
System.out.println(payload);
} catch (IOException e) {
throw new WebServiceClientException("Can not write the SOAP response into the out stream", e) {
private static final long serialVersionUID = -7118480620416458069L;
};
}
return true;
}
@Override
public boolean handleRequest(MessageContext messageContext) throws WebServiceClientException {
System.out.println("### SOAP REQUEST ###");
try {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
messageContext.getRequest().writeTo(buffer);
String payload = buffer.toString(java.nio.charset.StandardCharsets.UTF_8.name());
System.out.println(payload);
} catch (IOException e) {
throw new WebServiceClientException("Can not write the SOAP request into the out stream", e) {
private static final long serialVersionUID = -7118480620416458069L;
};
}
return true;
}
@Override
public boolean handleFault(MessageContext messageContext) throws WebServiceClientException {
System.out.println("### SOAP FAULT ###");
try {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
messageContext.getResponse().writeTo(buffer);
String payload = buffer.toString(java.nio.charset.StandardCharsets.UTF_8.name());
System.out.println(payload);
} catch (IOException e) {
throw new WebServiceClientException("Can not write the SOAP fault into the out stream", e) {
private static final long serialVersionUID = 3538336091916808141L;
};
}
return true;
}
}});
In each handle method you can easily use payload
to obtain raw soap messages.
Solution 5:[5]
First, SLF4J is just a simple facade. It means you still need a logging framework(e.g. java.util.logging, logback, log4j).
Second, Spring-ws uses Commons Logging interface that is another simple facade like SLF4J.
Finally, you can use below setting to enable Spring-ws message logging functionality.
log4j.logger.org.springframework.ws.client.MessageTracing.sent=DEBUG
log4j.logger.org.springframework.ws.client.MessageTracing.received=TRACE
log4j.logger.org.springframework.ws.server.MessageTracing.sent=DEBUG
log4j.logger.org.springframework.ws.server.MessageTracing.received=TRACE
Solution 6:[6]
Include the following in the log4j.properties
file...
- To log all server-side messages:
log4j.logger.org.springframework.ws.server.MessageTracing=DEBUG
- To log all client-side messages:
log4j.logger.org.springframework.ws.client.MessageTracing=TRACE
On the DEBUG
level - only the payload root element is logged
On the TRACE
level - the entire message content is logged
Lastly to log only the sent or received messages use the .sent
or .received
at the end of the configurations.
ex : log4j.logger.org.springframework.ws.server.MessageTracing.received=DEBUG
logs the client-side received massages payload root element
returning :
DEBUG WebServiceMessageReceiverHandlerAdapter:114 - Accepting incoming [org.springframework.ws.transport.http.HttpServletConnection@51ad62d9] to [http://localhost:8080/mock-platform/services]
For more info
Solution 7:[7]
Add a servlet filter to the spring ws (to move with org.springframework.web.servlet.DispatcherServlet) in web.xml
you can find a filter here http://www.wetfeetblog.com/servlet-filer-to-log-request-and-response-details-and-payload/431
inside the filter you can log as you wish
Solution 8:[8]
. . .
package com.example.Soap;
import org.springframework.ws.client.WebServiceClientException;
import org.springframework.ws.client.support.interceptor.ClientInterceptor;
import org.springframework.ws.context.MessageContext;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
public class LoggingVonfig implements ClientInterceptor {
@Override
public boolean handleResponse(MessageContext messageContext) throws WebServiceClientException {
System.out.println("### SOAP RESPONSE ###");
try {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
messageContext.getResponse().writeTo(buffer);
String payload = buffer.toString(java.nio.charset.StandardCharsets.UTF_8.name());
System.out.println(payload);
} catch (IOException e) {
throw new WebServiceClientException("Can not write the SOAP response into the out stream", e) {
private static final long serialVersionUID = -7118480620416458069L;
};
}
return true;
}
@Override
public boolean handleRequest(MessageContext messageContext) throws WebServiceClientException {
System.out.println("### SOAP REQUEST ###");
try {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
messageContext.getRequest().writeTo(buffer);
String payload = buffer.toString(java.nio.charset.StandardCharsets.UTF_8.name());
System.out.println(payload);
} catch (IOException e) {
throw new WebServiceClientException("Can not write the SOAP request into the out stream", e) {
private static final long serialVersionUID = -7118480620416458069L;
};
}
return true;
}
@Override
public boolean handleFault(MessageContext messageContext) throws WebServiceClientException {
System.out.println("### SOAP FAULT ###");
try {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
messageContext.getResponse().writeTo(buffer);
String payload = buffer.toString(java.nio.charset.StandardCharsets.UTF_8.name());
System.out.println(payload);
} catch (IOException e) {
throw new WebServiceClientException("Can not write the SOAP fault into the out stream", e) {
private static final long serialVersionUID = 3538336091916808141L;
};
}
return true;
}
@Override
public void afterCompletion(MessageContext messageContext, Exception e) throws WebServiceClientException {
}
}
. . .
This is logging Configuration class
. . .
package com.example.Soap;
import com.example.Soap.com.example.Soap.Add;
import com.example.Soap.com.example.Soap.AddResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ws.client.core.support.WebServiceGatewaySupport;
import org.springframework.ws.client.support.interceptor.ClientInterceptor;
import org.springframework.ws.soap.client.core.SoapActionCallback;
public class CalculatorClient extends WebServiceGatewaySupport {
private static Logger log = LoggerFactory.getLogger(CalculatorClient.class);
public com.example.Soap.com.example.Soap.AddResponse getaddition(com.example.Soap.com.example.Soap.Add addrequest){
com.example.Soap.com.example.Soap.Add add = new com.example.Soap.com.example.Soap.Add();
add.setIntB(addrequest.getIntB());
add.setIntA(addrequest.getIntA());
log.info("----------------------------------------------"+"Inbound Request"+"-----------------------");
com.example.Soap.com.example.Soap.AddResponse addResponse = (com.example.Soap.com.example.Soap.AddResponse) getWebServiceTemplate().marshalSendAndReceive("http://www.dneonline.com/calculator.asmx?wsdl",add,new SoapActionCallback("http://tempuri.org/Add"));
return addResponse;
}
public com.example.Soap.com.example.Soap.SubtractResponse getSubtract(com.example.Soap.com.example.Soap.Subtract subreq){
com.example.Soap.com.example.Soap.Subtract subtract=new com.example.Soap.com.example.Soap.Subtract();
subtract.setIntA(subreq.getIntA());
subtract.setIntB(subreq.getIntB());
com.example.Soap.com.example.Soap.SubtractResponse subtractResponse=(com.example.Soap.com.example.Soap.SubtractResponse) getWebServiceTemplate().marshalSendAndReceive("http://www.dneonline.com/calculator.asmx?wsdl",subtract,new SoapActionCallback("http://tempuri.org/Subtract"));
return subtractResponse;
}
public com.example.Soap.com.example.Soap.MultiplyResponse getMultiply(com.example.Soap.com.example.Soap.Multiply multiply)
{
com.example.Soap.com.example.Soap.Multiply multiply1=new com.example.Soap.com.example.Soap.Multiply();
multiply1.setIntA(multiply.getIntA());
multiply1.setIntB(multiply.getIntB());
com.example.Soap.com.example.Soap.MultiplyResponse multiplyResponse=(com.example.Soap.com.example.Soap.MultiplyResponse) getWebServiceTemplate().marshalSendAndReceive("http://www.dneonline.com/calculator.asmx?wsdl",multiply1,new SoapActionCallback("http://tempuri.org/Multiply"));
return multiplyResponse;
}
public com.example.Soap.com.example.Soap.DivideResponse getDivide(com.example.Soap.com.example.Soap.Divide divide){
com.example.Soap.com.example.Soap.Divide divide1=new com.example.Soap.com.example.Soap.Divide();
divide1.setIntA(divide.getIntA());
divide1.setIntB(divide.getIntB());
com.example.Soap.com.example.Soap.DivideResponse divideResponse=(com.example.Soap.com.example.Soap.DivideResponse) getWebServiceTemplate().marshalSendAndReceive("http://www.dneonline.com/calculator.asmx?wsdl",divide1,new SoapActionCallback("http://tempuri.org/Divide"));
return divideResponse;
}
public void MySoapClient() {
this.setInterceptors(new ClientInterceptor[] { new LoggingVonfig() });
}
}
. . .
This is my client class
. . .
package com.example.Soap;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.oxm.jaxb.Jaxb2Marshaller;
import org.springframework.ws.client.core.WebServiceTemplate;
@Configuration
public class CalculatorConfig {
@Bean
public Jaxb2Marshaller marshaller(){
Jaxb2Marshaller jaxb2Marshaller = new Jaxb2Marshaller();
// jaxb2Marshaller.setPackagesToScan("com.example.Soap.com.example.Soap");
jaxb2Marshaller.setContextPath("com.example.Soap.com.example.Soap"); // this will serilaize and unserialize it
return jaxb2Marshaller;
}
@Bean
public CalculatorClient calculatorClient(Jaxb2Marshaller jaxb2Marshaller){
WebServiceTemplate wsTemplate = new WebServiceTemplate();
CalculatorClient calculatorClient = new CalculatorClient();
calculatorClient.setDefaultUri("http://www.dneonline.com");
calculatorClient.setMarshaller(jaxb2Marshaller);
calculatorClient.setUnmarshaller(jaxb2Marshaller);
return calculatorClient;
}
}
. . .
configuration file
. . .
package com.example.Soap;
import com.example.Soap.com.example.Soap.Add;
import com.example.Soap.com.example.Soap.AddResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
@RestController
public class SoapApplication {
@Autowired
private CalculatorClient calculatorClient;
@PostMapping(value = "/add")
public com.example.Soap.com.example.Soap.AddResponse addelements(@RequestBody com.example.Soap.com.example.Soap.Add add){
return calculatorClient.getaddition(add);
}
@PostMapping(value = "/subtract")
public com.example.Soap.com.example.Soap.SubtractResponse addelements(@RequestBody com.example.Soap.com.example.Soap.Subtract subreq){
return calculatorClient.getSubtract(subreq);
}
@PostMapping(value = "/multiply")
public com.example.Soap.com.example.Soap.MultiplyResponse addelements(@RequestBody com.example.Soap.com.example.Soap.Multiply multiply){
return calculatorClient.getMultiply(multiply);
}
@PostMapping(value = "/divide")
public com.example.Soap.com.example.Soap.DivideResponse addelements(@RequestBody com.example.Soap.com.example.Soap.Divide divide){
return calculatorClient.getDivide(divide);
}
public static void main(String[] args) {
SpringApplication.run(SoapApplication.class, args);
}
}
. . .
These are my classes but still, I can't able to log all requests and responses in my console. I'm not getting where I have done wrong. I implemented Client configuration too.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Arpit Aggarwal |
Solution 2 | |
Solution 3 | |
Solution 4 | Rman |
Solution 5 | E.L. |
Solution 6 | Shanaka Jayalath |
Solution 7 | Supun Sameera |
Solution 8 | naga sri sai |