You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SpringBoot调用SOAP服务的请求响应拦截日志实现咨询

问题根因

你当前配置的EndpointInterceptor以及继承WsConfigurerAdapter的服务端配置,是Spring WS用于自身暴露SOAP服务端的拦截器逻辑,仅对接收外部SOAP请求的服务端生效。你现在的场景是作为客户端调用第三方SOAP服务,所以这套配置完全不会触发。

正确实现方案(适配你当前的JAX-WS原生客户端)

你用的是@WebClient注解标注的JAX-WS标准生成客户端,直接给端口对象绑定SOAP消息处理器即可实现请求响应日志记录。

步骤1:实现自定义日志SOAP处理器

import javax.xml.namespace.QName;
import javax.xml.soap.SOAPMessage;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;
import java.io.ByteArrayOutputStream;
import java.util.Collections;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class SoapLogHandler implements SOAPHandler<SOAPMessageContext> {

    private static final Logger log = LoggerFactory.getLogger(SoapLogHandler.class);

    @Override
    public Set<QName> getHeaders() {
        return Collections.emptySet();
    }

    @Override
    public boolean handleMessage(SOAPMessageContext context) {
        // 判断是请求还是响应
        boolean isOutbound = (boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
        SOAPMessage soapMessage = context.getMessage();
        try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
            soapMessage.writeTo(baos);
            String soapContent = baos.toString("UTF-8");
            if (isOutbound) {
                log.info("SOAP请求报文: {}", soapContent);
            } else {
                log.info("SOAP响应报文: {}", soapContent);
            }
        } catch (Exception e) {
            log.error("解析SOAP报文失败", e);
        }
        return true; // 返回true才会继续执行后续调用流程
    }

    @Override
    public boolean handleFault(SOAPMessageContext context) {
        // 处理SOAP Fault错误报文
        SOAPMessage faultMessage = context.getMessage();
        try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
            faultMessage.writeTo(baos);
            log.error("SOAP错误报文: {}", baos.toString("UTF-8"));
        } catch (Exception e) {
            log.error("解析SOAP错误报文失败", e);
        }
        return true;
    }

    @Override
    public void close(MessageContext context) {
        // 无需额外逻辑
    }
}

如果运行时找不到javax.xml.ws相关类,可在pom中引入依赖:

<dependency>
    <groupId>javax.xml.ws</groupId>
    <artifactId>jaxws-api</artifactId>
    <version>2.3.1</version>
</dependency>

步骤2:给客户端端口绑定处理器

修改你获取Producer端口的逻辑,添加处理器链即可:

// 你原来的业务方法里获取端口后添加
Producer p = serviceClient.getProducer();
// 绑定日志处理器
BindingProvider bindingProvider = (BindingProvider) p;
List<Handler> handlerChain = bindingProvider.getBinding().getHandlerChain();
handlerChain.add(new SoapLogHandler());
bindingProvider.getBinding().setHandlerChain(handlerChain);

// 后续正常调用接口
response = p.getData(request);

如果要全局生效不需要每次获取端口都加,也可以直接修改生成的ServiceClient类的getProducer方法,内部返回端口前就绑定处理器。

额外注意事项
  • 如果SOAP报文包含敏感字段(比如密码、手机号),可以在handleMessage方法里对报文内容做脱敏后再打印
  • 生产环境可以根据日志级别控制是否打印报文,避免磁盘IO过高
  • 报文里的特殊字符如果打印乱码,可以指定对应的编码格式,比如GBK等适配目标服务的编码

内容的提问来源于stack exchange,提问作者newcoder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 02:27:02