You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在Apache Axis2中记录request.xml和response.xml?求可行方案

Apache Axis2 记录SOAP请求/响应的可行实现方案

我之前在做Axis2的SOAP请求响应记录时,也踩过client-config.wsdd配置不生效的坑,给你一套亲测能跑的方案,分客户端和服务端两种场景来说:

一、客户端侧日志记录(无需client-config.wsdd,更可靠)

很多人用client-config.wsdd容易遇到配置路径找不到、加载顺序冲突的问题,我推荐直接通过代码注册Handler的方式,步骤如下:

  1. 自定义SOAPHandler实现
    写一个继承AbstractHandler的类,在invoke方法里捕获并打印请求/响应的SOAP消息:
import org.apache.axis2.AxisFault;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.handlers.AbstractHandler;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.io.StringWriter;
import java.nio.charset.StandardCharsets;

public class SOAPLoggingHandler extends AbstractHandler {
    private static final Log log = LogFactory.getLog(SOAPLoggingHandler.class);

    @Override
    public InvocationResponse invoke(MessageContext msgContext) throws AxisFault {
        try {
            if (msgContext.isRequest()) {
                // 记录请求消息
                StringWriter writer = new StringWriter();
                IOUtils.copy(msgContext.getEnvelope().getXMLStreamReader(), writer);
                log.info("=== SOAP Request Content ===");
                log.info(writer.toString());
            } else {
                // 记录响应消息
                String response = msgContext.getEnvelope().toString();
                log.info("=== SOAP Response Content ===");
                log.info(response);
            }
        } catch (Exception e) {
            log.error("Failed to log SOAP message", e);
        }
        return InvocationResponse.CONTINUE;
    }
}

注意:如果项目里没有commons-iocommons-logging依赖,需要手动引入对应jar包。

  1. 在客户端代码中注册Handler
    创建Axis2客户端时,把自定义Handler添加到请求和响应的处理链中:
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.context.ConfigurationContextFactory;

public class DemoSOAPClient {
    public static void main(String[] args) throws Exception {
        // 初始化配置上下文(无需指定配置文件)
        ConfigurationContext configContext = ConfigurationContextFactory.createConfigurationContextFromFileSystem(null, null);
        
        // 创建ServiceClient实例
        ServiceClient serviceClient = new ServiceClient(configContext, null);
        
        // 将日志Handler添加到请求和响应链的最前面
        serviceClient.getAxisConfiguration().getOutFlowHandlers().addFirst(new SOAPLoggingHandler());
        serviceClient.getAxisConfiguration().getInFlowHandlers().addFirst(new SOAPLoggingHandler());
        
        // 设置服务端点地址
        Options options = new Options();
        options.setTo(new EndpointReference("http://your-service-endpoint?wsdl"));
        serviceClient.setOptions(options);
        
        // 替换为你的实际服务调用代码
        // OMElement requestPayload = ...;
        // OMElement response = serviceClient.sendReceive(requestPayload);
    }
}

这种方式完全摆脱了对配置文件的依赖,避免了各种加载失败的问题,我在Axis2 1.7.9版本上测试完全正常。

二、服务端侧日志记录

如果需要在服务端记录所有请求响应,同样可以用Handler方案:

  1. 复用上面的SOAPLoggingHandler
  2. 修改Axis2的axis2.xml配置
    找到服务端WEB-INF/conf目录下的axis2.xml,在<phaseOrder>节点的InFlowOutFlow中添加自定义Handler:
<phaseOrder type="InFlow">
    <!-- 保留原有默认phase -->
    <phase name="CustomLoggingPhase">
        <handler name="SOAPLoggingHandler" class="com.your.package.SOAPLoggingHandler"/>
    </phase>
</phaseOrder>

<phaseOrder type="OutFlow">
    <!-- 保留原有默认phase -->
    <phase name="CustomLoggingPhase">
        <handler name="SOAPLoggingHandler" class="com.your.package.SOAPLoggingHandler"/>
    </phase>
</phaseOrder>

把Handler的class文件放到服务端的类路径下,重启服务后就能看到日志输出了。

三、常见问题排查

  • 如果日志没输出:检查commons-logging的配置文件(比如log4j.properties),确保日志级别设置为INFO或更低。
  • 版本兼容问题:不同Axis2版本的Handler API可能有细微差异,上述代码基于1.7.x版本测试通过,如果你用的是旧版本,可能需要调整部分方法。
  • 避免混合配置:不要同时用client-config.wsdd和代码注册Handler,容易出现处理链冲突。

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

火山引擎 最新活动