通過在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:[email protected]">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 。