Axis2 透過模組擴展功能,核心需實作兩個介面:Module(生命週期)與 Handler(業務邏輯)。本文以記錄 SOAP 訊息的 logging 模組為例,完整示範開發到部署流程。
Module 介面(LoggingModule)Handler 介面(LogHandler)META-INF/module.xmlaxis2.xml 註冊 Phaseservices.xml 引用模組.mar 部署package module;
import org.apache.axis2.*;
import org.apache.axis2.description.*;
import org.apache.axis2.modules.Module;
import org.apache.neethi.*;
public class LoggingModule implements Module {
public void init(ConfigurationContext ctx, AxisModule module) throws AxisFault {
System.out.println("init");
}
public void engageNotify(AxisDescription desc) throws AxisFault {}
public void shutdown(ConfigurationContext ctx) throws AxisFault {
System.out.println("shutdown");
}
public String[] getPolicyNamespaces() { return null; }
public void applyPolicy(Policy policy, AxisDescription desc) throws AxisFault {}
public boolean canSupportAssertion(Assertion assertion) { return true; }
}
Tomcat 啟動時載入模組會呼叫 init(),關閉呼叫 shutdown()。
package module;
import org.apache.axis2.*;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.engine.Handler;
import org.apache.axis2.handlers.AbstractHandler;
import org.apache.commons.logging.*;
public class LogHandler extends AbstractHandler implements Handler {
private static final Log log = LogFactory.getLog(LogHandler.class);
private String name;
public InvocationResponse invoke(MessageContext msgCtx) throws AxisFault {
log.info(msgCtx.getEnvelope().toString()); // 記錄完整 SOAP 封包
return InvocationResponse.CONTINUE;
}
public void revoke(MessageContext msgCtx) {
log.info(msgCtx.getEnvelope().toString());
}
public String getName() { return name; }
public void setName(String name) { this.name = name; }
}
核心 invoke() 在訊息流經時被呼叫,此處記錄請求/回應/錯誤訊息。
<module name="logging" class="module.LoggingModule">
<InFlow>
<handler name="InFlowLogHandler" class="module.LogHandler">
<order phase="loggingPhase"/>
</handler>
</InFlow>
<OutFlow>
<handler name="OutFlowLogHandler" class="module.LogHandler">
<order phase="loggingPhase"/>
</handler>
</OutFlow>
<OutFaultFlow>
<handler name="FaultOutFlowLogHandler" class="module.LogHandler">
<order phase="loggingPhase"/>
</handler>
</OutFaultFlow>
<InFaultFlow>
<handler name="FaultInFlowLogHandler" class="module.LogHandler">
<order phase="loggingPhase"/>
</handler>
</InFaultFlow>
</module>
四大流向(In/Out/Fault)皆掛載同一 Handler,Phase 名稱自訂為 loggingPhase。
在四個 <phaseOrder> 中加入 <phase name="loggingPhase"/>:
<phaseOrder type="InFlow"> ... <phase name="loggingPhase"/> </phaseOrder>
<phaseOrder type="OutFlow"> ... <phase name="loggingPhase"/> </phaseOrder>
<phaseOrder type="InFaultFlow"> ... <phase name="loggingPhase"/> </phaseOrder>
<phaseOrder type="OutFaultFlow"> ... <phase name="loggingPhase"/> </phaseOrder>
<service name="myService">
<module ref="logging"/>
<parameter name="ServiceClass">service.MyService</parameter>
<messageReceivers>...</messageReceivers>
</service>
logging.mar
├── module/
│ ├── LoggingModule.class
│ └── LogHandler.class
└── META-INF/
└── module.xml
service.aar
├── service/
│ └── MyService.class
└── META-INF/
└── services.xml
logging.mar 放入 WEB-INF/modules/service.aar 放入 WEB-INF/services/modules.list 需額外列入 logging.mar啟動 Tomcat,C# 呼叫 getGreeting("中國"),控制台輸出完整 SOAP 封包(見文末截圖)。
掌握此流程,即可開發驗證、加密、限流、追蹤等各類 Axis2 擴充模組。