首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Axis2 模組開發與部署實戰:以日誌模組為例

     編輯:Java 相關知識

1. 模組概覽

Axis2 為模組提供擴充支援。我們將自訂一個模組並部署至先前建立的 MyService。為給定 Web Service 部署自訂模組,步驟如下:

  1. 建立模組實作(Module Implementation)
  2. 建立處理器(Handlers)
  3. 修改 axis2.xml
  4. 修改 services.xml 使模組部署時生效
  5. 打包為 .mar(Module Archive)
  6. 在 Axis2 部署模組

2. 為 MyService 增加日誌模組

在範例程式中增加日誌模組。此模組包含一個處理器,記錄所有傳遞給它的訊息。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; }
}

步驟二:LogHandler

Axis2 模組可包含一或多個 handlers 在不同階段執行不同 SOAP 標頭處理。建立 handler 應實作 org.apache.axis2.engine.Handler。為簡單起見,org.apache.axis2.handlers.AbstractHandler 提供 Handler 介面抽象實作。針對日誌模組,建立 handler 包含方法:

  1. public void invoke(MessageContext ctx):控制權轉給 handler 時由 Axis2 引擎呼叫
  2. 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

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>

此檔案定義四個階段:

  • inflow:訊息到來時 handler 鏈執行
  • outflow:訊息發出時 handler 鏈執行
  • Outfaultflow:有錯誤且錯誤將發出時 handler 鏈執行
  • INfaultflow:有錯誤且錯誤將到來時 handler 鏈執行

標籤設定描述 handler 名稱、類別與執行階段:

<handler name="InFlowLogHandler" class="userguide.loggingmodule.LogHandler">
  <order phase="loggingPhase" />
</handler>

步驟四:修改 axis2.xml

此 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 將在這狀態執行。

步驟五:修改 services.xml

至今已為日誌模組建立所需類別與配置檔。下一步在服務中使用此模組。在 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 部署模組

部署模組於 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

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved