一、Axis2 中可用的部署方法
在 Axis2 中,可采用三種主要方式部署服務(wù):
o 將服務(wù)存檔文件放入存儲(chǔ)庫(kù)中。
o 使用存檔文件以編程方式創(chuàng)建服務(wù)。
o 將服務(wù)作為傳統(tǒng) Java 對(duì)象(Plain Old Java Object,POJO)部署。
在 Axis2 中,部署服務(wù)的最常用方法是直接將服務(wù)存檔文件復(fù)制或放置到存儲(chǔ)庫(kù)中(services 目錄)。如果使用基于 Axis2 WAR 文件的分發(fā)版本,則有兩個(gè)選擇:
o 手動(dòng)將存檔文件放置到存儲(chǔ)庫(kù)中。
o 使用 Web 控制臺(tái)上載服務(wù)。
以編程方式部署并非用戶需求,而是模塊創(chuàng)建者的需求,因?yàn)槟承┠K要求 Web 服務(wù)的部署提供模塊的全部功能。若要以編程方式創(chuàng)建服務(wù),需要使用 services.xml、類加載器(可用于加載您的類文件)和 AxisConfiguration。此方法的優(yōu)勢(shì)在于,您并不需要將服務(wù)存檔文件復(fù)制到存儲(chǔ)庫(kù)中,而且僅在運(yùn)行時(shí)服務(wù)才可見(jiàn)。清單 1 可幫助您形成對(duì)編程服務(wù)部署方法的基本認(rèn)識(shí)。
清單 1. 編程服務(wù)部署
AxisConfiguration axisConfig;
// you need to have reference to AxisConfiguration
File file = new File("Location of the file"");
ClassLoader clsLoader = new URLClassLoader(new URL[]{file.toURL()});
InputStream in = new FileInputStream("location of service.xml");
AxisService service = DeploymentEngine.buildService(in, clsLoader, axisConfig);
使用 Java 類部署服務(wù)是 Axis2 中提供的一項(xiàng)使用非常方便的功能,在這種情況下沒(méi)有必要生成服務(wù)存檔文件或 services.xml。唯一的要求是,必須在創(chuàng)建服務(wù)前將 Java 類放入類路徑中。在運(yùn)行時(shí),可以由模塊或服務(wù)創(chuàng)建新服務(wù)并進(jìn)行部署。在 Axis2 中部署 POJO 僅需要三行代碼,如清單 2 中所示。
清單 2. 在 Axis2 中部署 POJO
AxisService service = AxisService.createService(
MyService.class.getName(), axisConfig, RPCMessageReceiver.class);
axisConfig.addService(service);
二、Axis2模塊使用方法:
1.模塊
Axis2為模塊提供一個(gè)延伸的支持。我們現(xiàn)在自定義一個(gè)模塊并將其部署到我們先前創(chuàng)建的MyService。為一個(gè)給定的Web Service部署一個(gè)自定義的模塊,其步驟如下:
1)建立Module Implementation。
2)創(chuàng)建Handlers。
3)修改"axis2.xml"。
4)修改"services.xml",使你的模塊在部署期生效。
5)將其打包為一個(gè)".mar"(Module Archive)。
6)在Axis2上部署這個(gè)模塊。
2.為MyService增加一個(gè)日志模塊
現(xiàn)在我們?cè)谖覀兊睦映绦蛑性黾右粋€(gè)日志模塊。這個(gè)模塊包含一個(gè)handle,用來(lái)記錄所有傳遞給它的信息。Axis2使用". mar" (Module Archive)來(lái)部署模塊。下圖給出了需要被打包為".mar"文檔的文件結(jié)構(gòu)。
步驟一:日志模塊類
日志模塊是Axis2模塊的實(shí)現(xiàn)類。Axis2模塊應(yīng)該實(shí)現(xiàn)"org.apache.axis2.modules.Module"接口中的如下方法。
public void init(ConfigurationContext configContext, AxisModule module)
throws AxisFault;//Initialize the module
public void shutdown(AxisConfiguration axisSystem)
throws AxisFault;//End of module processing
public void engageNotify(AxisDescription axisDescription) throws AxisFault;
這些方法可以用來(lái)控制模塊的初始化和終止。通過(guò)參數(shù)AxisConfiguration,可提供給用戶完整的配置層次。模塊設(shè)計(jì)者可以使用它來(lái)很好的控制模塊的所有可能的操作。就這個(gè)簡(jiǎn)單的日志服務(wù)的例子而言,我們可以空實(shí)現(xiàn)這些類。
LoggingModule.java
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 {
// initialize the module
public void init(ConfigurationContext configContext, AxisModule module) throws AxisFault {}
public void engageNotify(AxisDescription axisDescription) throws AxisFault {}
// shutdown the module
public void shutdown(ConfigurationContext configurationContext) throws AxisFault {}
public String[] getPolicyNamespaces() {
return null;
}
}
步驟二:LogHandler
Axis2中的模塊可以包含一個(gè)或多個(gè)handlers用來(lái)在不同的階段執(zhí)行不同的SOAP頭處理。創(chuàng)建一個(gè)handler,應(yīng)該實(shí)現(xiàn)org.apache.axis2.engine.Handler。但是為簡(jiǎn)單起見(jiàn),org.apache.axis2.handlers.AbstractHandler提供了一個(gè)對(duì)Handler接口的抽象的實(shí)現(xiàn)。針對(duì)本例日志模塊,我們將創(chuàng)建一個(gè)handler包含以下方法:
1)"public void invoke(MessageContext ctx);"http://當(dāng)控制權(quán)轉(zhuǎn)到handler時(shí),由Axis2引擎調(diào)用。
2)"public void revoke(MessageContext ctx);"http://當(dāng)handlers被Axis2引擎撤銷時(shí)調(diào)用。
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"包含了每一個(gè)特定的模塊的部署配置信息。它應(yīng)該包含的細(xì)節(jié)有一個(gè)實(shí)現(xiàn)模塊的類(本例中是"LoggingModule"和各種各樣的將在不同階段運(yùn)行的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>
從這個(gè)文件中,我們可以看到"module.xml"定義了4個(gè)階段:
1)inflow-表示當(dāng)一個(gè)消息到來(lái)時(shí),這個(gè)handler鏈將運(yùn)行。
2)outflow-表示當(dāng)一個(gè)消息發(fā)出時(shí),這個(gè)handler鏈將運(yùn)行。
3)Outfaultflow-表示當(dāng)有一個(gè)錯(cuò)誤并且這個(gè)錯(cuò)蠼⒊鍪?,这个handler鏈將運(yùn)行。
4)INfalutflow-表示當(dāng)有一個(gè)錯(cuò)誤并且這個(gè)錯(cuò)誤將到來(lái)時(shí),這個(gè)handler鏈將運(yùn)行。
下面的標(biāo)簽設(shè)置描述了handler的名字,handler類和該handler將運(yùn)行的階段。
<handler name="InFlowLogHandler" class="userguide.loggingmodule.LogHandler">
<order phase="loggingPhase" />
</handler>
步驟四:修改"axis2.xml"
在這個(gè)handler中,階段"loggingPhase"是由這個(gè)模塊的設(shè)計(jì)者定義的。這不是一個(gè)預(yù)定義的handler階段,因此該模塊的設(shè)計(jì)者應(yīng)該將它在"axis2.xml"中聲明。只有這樣,Axis2引擎才能知道將這個(gè)handler放置在哪些“流”中(InFlow, OutFlow,等)。下面的xml定義展示了需要將日志模塊部署到Axis2引擎而對(duì)axis2.xml作的修改。(This is an extract of the phase section of the "axis2.xml".)
<!-- ================================================= -->
<!-- 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 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"在所有的流中都放置了,因此這個(gè)狀態(tài)將會(huì)被所有的消息流調(diào)用。既然我們的模塊與這個(gè)狀態(tài)相聯(lián)系,在這個(gè)模塊中的LogHandler將會(huì)在這個(gè)狀態(tài)被執(zhí)行。
步驟五:修改"services.xml"
到目前為止,我們已經(jīng)為這個(gè)日志模塊創(chuàng)建了所需的類和配置文件。下一步就是在我們的services中使用這個(gè)模塊。我們就在MyService中使用此模塊作演示。因此,我們需要修改MyService的"services.xml",以使得該模塊起作用。對(duì)"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>我們?cè)?services.xml"加入了一行"<module ref="logging"/>"。這行將告知Axis2引擎,這個(gè)日志模塊可以被這個(gè)service使用。在這個(gè)模塊中的handler將在各自的狀態(tài)被執(zhí)行(依據(jù)"module.xml"中的描述)。并將服務(wù)重新打包為MyServiceWithModule.aar。
步驟六:打包
在部署這個(gè)模塊之前,我們需要將這個(gè)模塊打包為一個(gè)".mar"文件。使用jar命令可以完成,將其打包為"logging.mar"。
步驟七:在Axis2上部署這個(gè)模塊
為了在Axis2上部署模塊,用戶必須自己新建一個(gè)目錄,取名為"modules",它的父目錄為servlet容器中的"webapps/axis2/WEB-INF",再將".mar"文件復(fù)制到此目錄下。本例中,為"logging.mar"。
注:為了看到日志,用戶必須將"log4j.properties"設(shè)置為log INFO。該配置文件在servlet容器下的"webapps\axis2\WEB-INF\classes"目錄。將"log4j.rootCategory= ERROR, LOGFILE"替換為"log4j.rootCategory=INFO, ERROR, LOGFILE"。
本文出自 “子 孑” 博客,請(qǐng)務(wù)必保留此出處http://zhangjunhd.blog.51cto.com/113473/25593
聯(lián)系客服