|
SCA中Web Service的發(fā)布及調(diào)用分析
在SCA規(guī)范中提供了Web Service Binding,可以把服務(wù)對外暴露為Web Service,同時也可以消費外部提供的Web Service服務(wù),這一功能在EOS中是如何實現(xiàn)的呢,下面分兩部分進(jìn)行詳細(xì)的說明(在EOS當(dāng)中,Web Service容器采用axis2來完成)。
一、對外暴露為Web Service
把服務(wù)對外暴露為Web Service,通過在Service上添加binding.ws節(jié)點來實現(xiàn)。在服務(wù)端解析構(gòu)件的服務(wù)時,解析器發(fā)現(xiàn)有Web Service Binding,則其處理過程如下:
1、根據(jù)服務(wù)的接口類型生成axis2對象AxisService,在其中分為兩種情況
(a) 接口類型為WSDL定義的接口,則會利用其對應(yīng)的WSDL文件對應(yīng)的Definition對象生成,在此主要用到了axis2提供的WSDLToAxisServiceBuilder.populateService()方法來完成。
(b) 接口類型采用Java接口進(jìn)行描述,則會利用接口提供的Java類生成,在此主要通過增加Parameter參數(shù)來完成,代碼樣例如下:
AxisService axisService = new AxisService();
Parameter classParam = new Parameter(Constants.SERVICE_CLASS, "interfaceName");
axisService.addParameter(classParam);
2、接管Web Service允許調(diào)用的操作
(a) 針對AxisService中定義的所有操作AxisOperation,定義其接管的業(yè)務(wù)方法處理,這通過設(shè)置AxisOperation的MessageReceiver來完成。
(b) 擴(kuò)展axis2中的抽象類AbstractInMessageReceiver,實現(xiàn)抽象方法invokeBusinessLogic來完成業(yè)務(wù)操作的調(diào)用。
3、把生成的AxisService對象加入到axis2的配置上下文中
(a) 根據(jù)配置文件axis2.xml生成AxisConfiguration對象
(b) 利用生成的AxisConfiguration對象,建立配置上下文ConfigurationContext
(c) AxisConfiguration對象中添加生成的AxisService
4、建立Axis2ServiceServlet,監(jiān)聽請求
(a) 新建對象Axis2ServiceServlet servlet = new Axis2ServiceServlet();
(b) 利用上下文對Servlet初始化servlet.init(configContext);
(c) 設(shè)置上下文的URL,也就是要監(jiān)聽的URL。configContext.setContextRoot(servletURI);
經(jīng)過以上步驟,服務(wù)端針對每個URL都生成了一個AxisServlet監(jiān)聽客戶的請求,每個請求的參數(shù)都以O(shè)Melement類型進(jìn)行了封裝。
服務(wù)調(diào)用的序列圖如下:

二、引用外部的Web Service
在構(gòu)件中可以通過引用調(diào)用外部的服務(wù),如要引用外部的Web Service,在引用(reference)節(jié)點上添加binding.ws來實現(xiàn),通過屬性wsdlElement指定引用外部Web Service的address。其處理過程如下:
1、 針對每個reference調(diào)用,生成一個axisClient,
(a) 根據(jù)wsdlElement屬性值,找到對應(yīng)的WSDL,生成AxisService(步驟同上1(a))。
(b) 生成axis的配置上下文(步驟同上(3))。
(c) 生成Axis調(diào)用客戶端ServiceClient client = ServiceClient(configContext, axisService);
2、 調(diào)用時,解析傳入的Message,發(fā)送請求
(a) 根據(jù)要調(diào)用的操作,生成OperationClient,方式為ServiceClient.createClient(wsdlOperationName)
(b) 解析傳入的OMelement Message,生成SOAPEnvelope。把Message中的值添加到SOAPEnvelope的Body當(dāng)中,進(jìn)行數(shù)據(jù)傳遞。
(c)生成傳遞信息上下文MessageContext
(i) 生成MessageContext,并設(shè)置其信封,MessageContext.setEnvelope(SOAPEnvelope);。
(ii) 設(shè)置調(diào)用服務(wù)器的Endpoint
MessageContext. .setTo(new EndpointReference("address"));
(iii) 把生成的信息上下文MessageContext添加到OperationClient當(dāng)中
operationClient.addMessageContext(MessageContext);
(d)發(fā)起請求
operationClient.execute(true);
3、 返回調(diào)用結(jié)果,從返回的SOAP信息中取得結(jié)果值
MessageContext responseMC = operationClient.getMessageContext("In");
OMElement response = responseMC.getEnvelope().getBody().getFirstElement();
經(jīng)過上述步驟,就完成了一個完整的Web Service客戶端的調(diào)用,其序列圖如下:

|