Axis2 為模組提供擴充支援。我們將自訂一個模組並部署至先前建立的 MyService。為給定 Web Service 部署自訂模組,步驟如下:
axis2.xmlservices.xml 使模組部署時生效.mar(Module Archive)在範例程式中增加日誌模組。此模組包含一個處理器,記錄所有傳遞給它的訊息。Axis2 使用 .mar 部署模組。下圖給出需打包為 .mar 的檔案結構。

日誌模組為 Axis2 模組實作類別。Axis2 模組應實作 org.apache.axis2.modules.Module 介面方法:
public void init(ConfigurationContext configContext, AxisModule module) throws AxisFault; // 初始化模組
public void shutdown(AxisConfiguration axisSystem) throws AxisFault; // 結束模組處理
public void engageNotify(AxisDescription axisDescription) throws AxisFault;
這些方法可控制模組初始化與終止。透過 AxisConfiguration 參數提供完整配置層次,模組設計者可良好控制模組所有可能操作。對此簡單日誌服務範例,可空實作這些類別。
package userguide.loggingmodule;
import org.apache.axis2.AxisFault;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.description.AxisDescription;
import org.apache.axis2.description.AxisModule;
import org.apache.axis2.modules.Module;
public class LoggingModule implements Module {
public void init(ConfigurationContext configContext, AxisModule module) throws AxisFault {}
public void engageNotify(AxisDescription axisDescription) throws AxisFault {}
public void shutdown(ConfigurationContext configurationContext) throws AxisFault {}
public String[] getPolicyNamespaces() { return null; }
}
Axis2 模組可包含一或多個 handlers 在不同階段執行不同 SOAP 標頭處理。建立 handler 應實作 org.apache.axis2.engine.Handler。為簡單起見,org.apache.axis2.handlers.AbstractHandler 提供 Handler 介面抽象實作。針對日誌模組,建立 handler 包含方法:
public void invoke(MessageContext ctx):控制權轉給 handler 時由 Axis2 引擎呼叫public void revoke(MessageContext ctx):handlers 被 Axis2 引擎撤銷時呼叫package userguide.loggingmodule;
import org.apache.axis2.AxisFault;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.engine.Handler;
import org.apache.axis2.handlers.AbstractHandler;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import javax.xml.namespace.QName;
@SuppressWarnings("serial")
public class LogHandler extends AbstractHandler implements Handler {
private static final Log log = LogFactory.getLog(LogHandler.class);
private QName name;
public QName getName() { return name; }
public void invoke(MessageContext msgContext) throws AxisFault {
log.info(msgContext.getEnvelope().toString());
}
public void revoke(MessageContext msgContext) {
log.info(msgContext.getEnvelope().toString());
}
public void setName(QName name) { this.name = name; }
}
module.xml 包含每個特定模組部署配置資訊:實作模組類別(本例 LoggingModule)與各階段執行的 handlers。本例日誌模組 module.xml:
<module name="logging" class="userguide.loggingmodule.LoggingModule">
<inflow>
<handler name="InFlowLogHandler" class="userguide.loggingmodule.LogHandler">
<order phase="loggingPhase" />
</handler>
</inflow>
<outflow>
<handler name="OutFlowLogHandler" class="userguide.loggingmodule.LogHandler">
<order phase="loggingPhase"/>
</handler>
</outflow>
<Outfaultflow>
<handler name="FaultOutFlowLogHandler" class="userguide.loggingmodule.LogHandler">
<order phase="loggingPhase"/>
</handler>
</Outfaultflow>
<INfaultflow>
<handler name="FaultInFlowLogHandler" class="userguide.loggingmodule.LogHandler">
<order phase="loggingPhase"/>
</handler>
</INfaultflow>
</module>
此檔案定義四個階段:
標籤設定描述 handler 名稱、類別與執行階段:
<handler name="InFlowLogHandler" class="userguide.loggingmodule.LogHandler">
<order phase="loggingPhase" />
</handler>
此 handler 中階段 loggingPhase 由模組設計者定義,非預定義 handler 階段,故設計者應在 axis2.xml 宣告。只有這樣 Axis2 引擎才知將 handler 放置哪些「流」中。下列 XML 定義展示部署日誌模組至 Axis2 引擎需對 axis2.xml 修改(節錄 axis2.xml phase 區段):
<!-- ================================================= -->
<!-- Phases -->
<!-- ================================================= -->
<phaseOrder type="inflow">
<!-- System pre defined phases -->
<phase name="TransportIn"/>
<phase name="PreDispatch"/>
<phase name="Dispatch" class="org.apache.axis2.engine.DispatchPhase">
<handler name="AddressingBasedDispatcher" class="org.apache.axis2.engine.AddressingBasedDispatcher">
<order phase="Dispatch"/>
</handler>
<handler name="RequestURIBasedDispatcher" class="org.apache.axis2.engine.RequestURIBasedDispatcher">
<order phase="Dispatch"/>
</handler>
<handler name="SOAPActionBasedDispatcher" class="org.apache.axis2.engine.SOAPActionBasedDispatcher">
<order phase="Dispatch"/>
</handler>
<handler name="SOAPMessageBodyBasedDispatcher" class="org.apache.axis2.engine.SOAPMessageBodyBasedDispatcher">
<order phase="Dispatch"/>
</handler>
<handler name="InstanceDispatcher" class="org.apache.axis2.engine.InstanceDispatcher">
<order phase="PostDispatch"/>
</handler>
</phase>
<!-- System pre defined phases -->
<!-- After Postdispatch phase module author or service author can add any phase he want -->
<phase name="OperationInPhase"/>
<phase name="loggingPhase"/>
</phaseOrder>
<phaseOrder type="outflow">
<!-- user can add his own phases to this area -->
<phase name="OperationOutPhase"/>
<phase name="loggingPhase"/>
<!-- system predefined phase -->
<!-- these phase will run irrespective of the service -->
<phase name="PolicyDetermination"/>
<phase name="MessageOut"/>
</phaseOrder/>
<phaseOrder type="INfaultflow">
<!-- user can add his own phases to this area -->
<phase name="OperationInFaultPhase"/>
<phase name="loggingPhase"/>
</phaseOrder>
<phaseOrder type="Outfaultflow">
<!-- user can add his own phases to this area -->
<phase name="OperationOutFaultPhase"/>
<phase name="loggingPhase"/>
<phase name="PolicyDetermination"/>
<phase name="MessageOut"/>
</phaseOrder>
自訂階段 loggingPhase 在所有流中放置,故此狀態將被所有訊息流呼叫。因模組與此狀態關聯,模組中 LogHandler 將在這狀態執行。
至今已為日誌模組建立所需類別與配置檔。下一步在服務中使用此模組。在 MyService 中示範。需修改 MyService services.xml 使模組生效:
<service name="MyServiceWithModule">
<description>
This is a sample Web Service with a logging module engaged.
</description>
<module ref="logging"/>
<parameter name="ServiceClass" locked="false">
userguide.example1.MyService
</parameter>
<operation name="echo">
<messageReceiver class="org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/>
</operation>
<operation name="ping">
<messageReceiver class="org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/>
</operation>
</service>
在 services.xml 加入 <module ref="logging"/>。此行告知 Axis2 引擎日誌模組可被此服務使用。模組中 handlers 將在各自狀態執行(依 module.xml 描述)。重新打包為 MyServiceWithModule.aar。
部署模組前需打包為 .mar 檔案。使用 jar 指令完成,打包為 logging.mar。
部署模組於 Axis2,使用者必須自行新建目錄命名 modules,父目錄為 servlet 容器 webapps/axis2/WEB-INF,將 .mar 檔複製至此目錄。本例為 logging.mar。
注意: 為看到日誌,使用者必須將
log4j.properties設為 log INFO。配置檔在 servlet 容器webapps\axis2\WEB-INF\classes目錄。將log4j.rootCategory=ERROR, LOGFILE替換為log4j.rootCategory=INFO, ERROR, LOGFILE。
本文出自「子孑」部落格,請務必保留出處:https://zhangjunhd.blog.51cto.com/113473/25593