如何记录Axis 1.4 的WebService SOAP消息?

本文介绍了如何在Axis 1.4中记录WebService的SOAP消息,包括全局和局部配置方法,并指出了Axis自带LogHandler的不足,如无法控制日志大小和滚动。通过引入common-logging和log4j,作者提供了一个改进的MyLogHandler,实现了日志大小控制和滚动功能。详细代码和log4j配置参考链接给出。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

通过在Web应用WEB-INF目录下的server-config.wsdd文件中添加Handler配置实现

一、记录所有WebService的SOAP消息(全局配置方式)

<?xml version="1.0" encoding="UTF-8"?>
<deployment xmlns="http://xml.apache.org/axis/wsdd/"
	xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">

	<handler name="URLMapper" type="java:org.apache.axis.handlers.http.URLMapper" />

	<!-- (1)Axis自带的LogHandler配置 -->
	<handler name="log" type="java:org.apache.axis.handlers.LogHandler">
		<parameter name="LogHandler.fileName" value="C:\axis.log" /> <!-- 目录必须存在 -->
	</handler>

	<!-- (2)全局配置 -->
	<globalConfiguration>
		<parameter name="disablePrettyXML" value="false" />
		<requestFlow>
			<handler type="LogHandler" />
		</requestFlow>
		<responseFlow>
			<handler type="LogHandler" />
		</responseFlow>
	</globalConfiguration>

	<!-- 自定义的WebService配置 -->
	<service name="HelloWordWSDD" provider="java:RPC">
		<requestFlow>
			<chain type="HelloWorldChain" />
		</requestFlow>
		<parameter name="allowedMethods" value="*" />
		<parameter name="scope" value="request" />
		<parameter name="className" value="com.yakoo5.axis.ws.HelloWordWSDD" />
	</service>

	<!-- (3)transport配置 -->	
	<transport name="http" pivot="java:org.apache.axis.transport.http.HTTPSender" />
	<transport name="local" pivot="java:org.apache.axis.transport.local.LocalSender" />
	<transport name="java" pivot="java:org.apache.axis.transport.java.JavaSender" />	
		
</deployment>

二、仅记录特定WebService的SOAP消息(局部配置)

<?xml version="1.0" encoding="UTF-8"?>
<deployment xmlns="http://xml.apache.org/axis/wsdd/"
	xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">

	<handler name="URLMapper" type="java:org.apache.axis.handlers.http.URLMapper" />

	<!-- (1)Axis自带的LogHandler配置 -->
	<handler name="log" type="java:org.apache.axis.handlers.LogHandler">
		<parameter name="LogHandler.fileName" value="C:\axis.log" /> <!-- 目录必须存在 -->
	</handler>

	<!-- 自定义的WebService配置 -->
	<service name="HelloWordWSDD" provider="java:RPC">
		<!-- (2)局部配置 -->
		<requestFlow>
			<handler type="LogHandler" />
			<chain type="HelloWorldChain" />
		</requestFlow>
		<responseFlow>
			<handler type="LogHandler" />
		</responseFlow>
		<parameter name="allowedMethods" value="*" />
		<parameter name="scope" value="request" />
		<parameter name="className" value="com.yakoo5.axis.ws.HelloWordWSDD" />
	</service>

	<!-- (3)transport配置 -->	
	<transport name="http" pivot="java:org.apache.axis.transport.http.HTTPSender" />
	<transport name="local" pivot="java:org.apache.axis.transport.local.LocalSender" />
	<transport name="java" pivot="java:org.apache.axis.transport.java.JavaSender" />	
		
</deployment>

三、Axis自带LogHandler的不足

        Axis的LogHandler实际上是通过FileWriter来构建字符输出流来输出日志内容,由于是直接通过FileWriter写入文件,因此也无法实现类似于Log4j的日志大小控制、滚动日志等功能。

        通过Axis 1.4的LogHandler类的源码可以知道LogHandler调用自身的logMessages方法来记录SOAP消息,源码如下:

    private void logMessages(MessageContext msgContext) throws AxisFault {
        try {
            PrintWriter writer   = null;

            writer = getWriter();

            Message inMsg = msgContext.getRequestMessage();
            Message outMsg = msgContext.getResponseMessage();

            writer.println( "=======================================================" );
            if (start != -1) {
                writer.println( "= " + Messages.getMessage("elapsed00",
                       "" + (System.currentTimeMillis() - start)));
            }
            writer.println( "= " + Messages.getMessage("inMsg00",
                   (inMsg == null ? "null" : inMsg.getSOAPPartAsString())));
            writer.println( "= " + Messages.getMessage("outMsg00",
                   (outMsg == null ? "null" : outMsg.getSOAPPartAsString())));
            writer.println( "=======================================================" );

            //START FIX: http://nagoya.apache.org/bugzilla/show_bug.cgi?id=16646
            if (!writeToConsole) {
              writer.close();
            }
            //END FIX: http://nagoya.apache.org/bugzilla/show_bug.cgi?id=16646

        } catch( Exception e ) {
            log.error( Messages.getMessage("exception00"), e );
            throw AxisFault.makeFault(e);
        }
    }

        logMessages方法实际上试通过getWriter()返回的一个PrintWriter来打印日志,getWriter()方法源码如下:

    private PrintWriter getWriter() throws IOException {
        PrintWriter writer;

        // Allow config info to control where we write.
        if (writeToConsole) {
            // Writing to the console
            writer = new PrintWriter(System.out);
        } else {
            // Writing to a file.
            if (filename == null) {
                filename = "axis.log";
            }
            writer = new PrintWriter(new FileWriter( filename, true ));
        }
        return writer;
    }

         PrintWriter通过传入的FileWriter来构建字符输出流输出日志内容,自然也无法实现类似于Log4j的日志大小控制、滚动日志等功能。

        下面我们通过使用common-logging和lo4j日志组件来改进这个LogHandler。

四、改进的MyLogHandler(实现日志大小控制、滚动日志等功能)

        通过Apache的common-logging来替换原有的PrintWriter记录SOAP消息,源码如下:

package yakoo5.ws.axis.handlers;

import org.apache.axis.AxisFault;
import org.apache.axis.Message;
import org.apache.axis.MessageContext;
import org.apache.axis.components.logger.LogFactory;
import org.apache.axis.handlers.BasicHandler;
import org.apache.axis.utils.Messages;
import org.apache.commons.logging.Log;

/**
 * Axis 1.x LogHandler 记录WebService交互的request和response soap报文<br>
 * <p>
 * 作为Axis 1.x提供的{@link org.apache.axis.handlers.LogHandler}的替换, 可将SOAP消息记录到commons-logging组件的日志实现组件配置的日志文件中。
 * </p>
 * 
 * @author <a href="mailto:yakoo5@163.com">yakoo5</a>
 */
public class MyLogHandler extends BasicHandler {
    private static final long serialVersionUID = 1L;
    protected static Log log = LogFactory.getLog(LogHandler.class.getName());

    long start = -1;

    /*
     * (non-Javadoc)
     * @see org.apache.axis.Handler#invoke(org.apache.axis.MessageContext)
     */
    @Override
    public void invoke(MessageContext msgContext) throws AxisFault {
        log.debug("Enter: LogHandler::invoke");
        if (msgContext.getPastPivot() == false) {
            start = System.currentTimeMillis();
        } else {
            logMessages(msgContext);
        }
        log.debug("Exit: LogHandler::invoke");
    }

    // 记录消息
    private void logMessages(MessageContext msgContext) throws AxisFault {
        try {
            Message inMsg = msgContext.getRequestMessage();
            Message outMsg = msgContext.getResponseMessage();

            log.info("=======================================================");
            if (start != -1) {
                log.info("= " + Messages.getMessage("elapsed00", "" + (System.currentTimeMillis() - start)));
            }
            log.info("= " + Messages.getMessage("inMsg00", (inMsg == null ? "null" : inMsg.getSOAPPartAsString())));
            log.info("= " + Messages.getMessage("outMsg00", (outMsg == null ? "null" : outMsg.getSOAPPartAsString())));
            log.info("=======================================================");
        } catch (Exception e) {
            log.error(Messages.getMessage("exception00"), e);
            throw AxisFault.makeFault(e);
        }
    }

    @Override
    public void onFault(MessageContext msgContext) {
        try {
            logMessages(msgContext);
        } catch (AxisFault axisFault) {
            log.error(Messages.getMessage("exception00"), axisFault);
        }
    }

}

        MyLogHandler的server-config.wsdd配置(同LogHandler):

<handler name="LogHandler" type="java:yakoo5.ws.axis.handlers.MyLogHandler" />


具体的自定义的日志大小、日志文件数量、日志滚动配置可通过log4j的配置实现,log4j的配置可参考笔者转载的以下文章:

(1)log4j配置详解:http://blog.youkuaiyun.com/yakoo5/article/details/6629300 ;

(2)log4j使用案例:http://blog.youkuaiyun.com/yakoo5/article/details/5273032 。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值