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

来源:互联网 发布:java web实训心得体会 编辑:程序博客网 时间:2024/05/16 02:18

通过在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.csdn.net/yakoo5/article/details/6629300 ;

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

0 0
原创粉丝点击