ChatGPT解决这个技术问题 Extra ChatGPT

如何让 Spring WebServices 记录所有 SOAP 请求?

我需要在 CommonLogFormat(参见 http://en.wikipedia.org/wiki/Common_Log_Format)中记录的所有 SOAP 请求,加上持续时间(处理请求所花费的时间)。

最好的方法是什么?看起来可以为 Spring WebServices 配置 log4j,但它会记录我感兴趣的所有值吗? http://pijava.wordpress.com/2009/12/04/spring-webservice-soap-requestresponse-logging-with-log4j/

编辑:我们实际上使用的是 SLF4J,而不是 Log4j。此外,看起来可以通过配置 PayloadLoggingInterceptor 来做到这一点:http://static.springsource.org/spring-ws/site/reference/html/server.html#server-endpoint-interceptor

但我不确定日志消息会去哪里。我将该拦截器添加到我们的拦截器中,但没有看到任何日志消息。


A
Arpit Aggarwal

对于 Spring Boot 项目,在 application.properties 中添加以下内容对我有用:

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

好的。最初我很困惑,因为 Sent 代码流仅使用 DEBUG 而不是 TRACE,因此它没有打印 Request 的完整 SOAP 消息详细信息。但后来我意识到收到的消息处于 TRACE 模式,因此它既显示响应,也显示响应所针对的完整请求消息正文
J
Jonas Geiregat

您可以使用它来记录传入和传出 Web 服务调用的原始有效负载。我不确定如何记录 Web 服务通信花费的时间。

   <!-- 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>

可在 http://static.springsource.org/spring-ws/site/reference/html/common.html#logging 找到更多详细信息


我在 spring-ws 1.5.9 中找不到这些类
它们不是类,它们是登录到的类别。请参阅 static.springsource.org/spring-ws/site/reference/html/… 上的文档
PayloadLoggingInterceptor 也可能会有所帮助。原始海报添加了一个链接。
我会这么认为。试试看,让我们知道!
更简洁的语法:
a
aram063

这对我有用。它记录发送的请求消息和收到的响应。您可以计算出从日志中花费的总时间。

log4j.logger.org.springframework.ws.client.MessageTracing.sent=TRACE
log4j.logger.org.springframework.ws.client.MessageTracing.received=TRACE

显然,这应该添加到您的 log4j.properties 文件中。
R
Rman

如果您有自己的日志记录系统,则以下拦截器可以替代记录 SOAP 消息。

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

在每个句柄方法中,您都可以轻松地使用 payload 来获取原始肥皂消息。


最后一个不使用硬编码属性文件或spring XML的答案!
精度,对某些人来说可能很明显,但方法正是:org.springframework.ws.client.core.support.WebServiceGatewaySupport#setInterceptors,实现的接口是 org.springframework.ws.client.support.interceptor.ClientInterceptor,您还需要为此实现一个空的 afterCompletion 方法。
E
E.L.

首先,SLF4J 只是一个简单的门面。这意味着您仍然需要一个日志框架(例如 java.util.logging、logback、log4j)。

其次,Spring-ws 使用 Commons Logging 接口,它是另一个类似 SLF4J 的简单外观。

最后,您可以使用以下设置来启用 Spring-ws 消息记录功能。

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

这对我有用。谢谢。有人知道如何在日志中漂亮地打印 SOAP 吗?
S
Shanaka Jayalath

log4j.properties 文件中包含以下内容...

记录所有服务器端消息:log4j.logger.org.springframework.ws.server.MessageTracing=DEBUG 记录所有客户端消息:log4j.logger.org.springframework.ws.client.MessageTracing=TRACE

DEBUG 级别 - 仅记录有效负载根元素

TRACE 级别 - 记录整个消息内容

最后,要仅记录发送或接收的消息,请在配置末尾使用 .sent.received

例如:log4j.logger.org.springframework.ws.server.MessageTracing.received=DEBUG 记录客户端收到的消息负载根元素返回:

DEBUG WebServiceMessageReceiverHandlerAdapter:114 - Accepting incoming [org.springframework.ws.transport.http.HttpServletConnection@51ad62d9] to [http://localhost:8080/mock-platform/services]

更多info


S
Supun Sameera

在 web.xml 中向 spring ws 添加一个 servlet 过滤器(与 org.springframework.web.servlet.DispatcherServlet 一起移动)

您可以在此处找到过滤器http://www.wetfeetblog.com/servlet-filer-to-log-request-and-response-details-and-payload/431

在过滤器内,您可以根据需要记录


链接不再有效
n
naga sri sai
. . .
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);
    }

}
.  . .

这些是我的课程,但我仍然无法在控制台中记录所有请求和响应。我没有得到我做错的地方。我也实现了客户端配置。


如果您有新问题,请点击 Ask Question 按钮提出问题。如果有助于提供上下文,请包含指向此问题的链接。 - From Review
无论如何......只需在客户端调用之前调用您的方法 MySoapClient()