本文為原創(chuàng),如需轉(zhuǎn)載,請注明作者和出處,謝謝!
上一篇:WebService大講堂之Axis2(5):會(huì)話(Session)管理
在《WebService大講堂之Axis2(5):會(huì)話(Session)管理》一文中介紹了如何使用Axis2來管理同一個(gè)服務(wù)的會(huì)話,但對于一個(gè)復(fù)雜的系統(tǒng),不可能只有一個(gè)WebService服務(wù),例如,至少會(huì)有一個(gè)管理用戶的WebService(用戶登錄和注冊)以及處理業(yè)務(wù)的WebService。象這種情況,就必須在多個(gè)WebService服務(wù)之間共享會(huì)話狀態(tài),也稱為跨服務(wù)會(huì)話(Session)管理。實(shí)現(xiàn)跨服務(wù)會(huì)話管理與實(shí)現(xiàn)同一個(gè)服務(wù)的會(huì)話管理的步驟類似,但仍然有一些差別,實(shí)現(xiàn)跨服務(wù)會(huì)話管理的步驟如下:
實(shí)現(xiàn)跨服務(wù)的Session管理需要如下三步:
1. 使用MessageContext和ServiceGroupContext獲得與設(shè)置key-value對。
2. 為要進(jìn)行Session管理的WebService類所對應(yīng)的<service>元素添加一個(gè)scope屬性,并將該屬性值設(shè)為application。
3. 在客戶端使用setManageSession(true)打開Session管理功能。
從上面的步驟可以看出,實(shí)現(xiàn)跨服務(wù)會(huì)話管理與實(shí)現(xiàn)同一個(gè)服務(wù)的會(huì)話管理在前兩步上存在著差異,而第3步是完全一樣的。下面是一個(gè)跨服務(wù)的會(huì)話管理的實(shí)例。在這個(gè)例子中有兩個(gè)WebService類:LoginService和SearchService,代碼如下:
LoginService.java
package service;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.context.ServiceGroupContext;
public class LoginService
{
public boolean login(String username, String password)
{
if("bill".equals(username) && "1234".equals(password))
{
// 第1步:設(shè)置key-value對
MessageContext mc = MessageContext.getCurrentMessageContext();
ServiceGroupContext sgc = mc.getServiceGroupContext();
sgc.setProperty("login", "成功登錄");
return true;
}
else
{
return false;
}
}
public String getLoginMsg()
{
// 第1步:獲得key-value對中的value
MessageContext mc = MessageContext.getCurrentMessageContext();
ServiceGroupContext sgc = mc.getServiceGroupContext();
return (String)sgc.getProperty("login");
}
}
SearchService.java
package service;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.context.ServiceGroupContext;
public class SearchService
{
public String findByName(String name)
{
// 第1步:獲得key-value對中的value
MessageContext mc = MessageContext.getCurrentMessageContext();
ServiceGroupContext sgc = mc.getServiceGroupContext();
if (sgc.getProperty("login") != null)
return "找到的數(shù)據(jù)<" + name + ">";
else
return "用戶未登錄";
}
}
services.xml文件中的配置代碼如下:
<serviceGroup>
<!-- 第2步:添加scope屬性,并設(shè)置屬性值為application -->
<service name="loginService" scope="application">
<description>
登錄服務(wù)
</description>
<parameter name="ServiceClass">
service.LoginService
</parameter>
<messageReceivers>
<messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out"
class="org.apache.axis2.rpc.receivers.RPCMessageReceiver" />
</messageReceivers>
</service>
<!-- 第2步:添加scope屬性,并設(shè)置屬性值為application -->
<service name="searchService" scope="application">
<description>
搜索服務(wù)
</description>
<parameter name="ServiceClass">
service.SearchService
</parameter>
<messageReceivers>
<messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out"
class="org.apache.axis2.rpc.receivers.RPCMessageReceiver" />
</messageReceivers>
</service>
</serviceGroup>
第3步與《WebService大講堂之Axis2(5):會(huì)話(Session)管理》一文中介紹的方法類似。
下面是使用兩個(gè)stub類的對象實(shí)例訪問上面實(shí)現(xiàn)的兩個(gè)WebService的客戶端代碼:
LoginServiceStub stub = new LoginServiceStub();
LoginServiceStub.Login login = new LoginServiceStub.Login();
login.setUsername("bill");
login.setPassword("1234");
if(stub.login(login).local_return)
{
System.out.println(stub.getLoginMsg().local_return);
SearchServiceStub searchStub = new SearchServiceStub();
SearchServiceStub.FindByName fbn = new SearchServiceStub.FindByName();
fbn.setName("abc");
System.out.println(searchStub.findByName(fbn).local_return);
}
在執(zhí)行上面的代碼后,將輸出如下的信息:
成功登錄
找到的數(shù)據(jù)<abc>
讀者可以將scope屬性值改成transportsession,看看會(huì)輸出什么!
實(shí)際上,Axis2的會(huì)話管理也是通過Cookie實(shí)現(xiàn)的,與Web應(yīng)用中的Session管理類似。如果讀者使用C#訪問支持會(huì)話(在同一個(gè)服務(wù)中的會(huì)話管理)的WebService,需要指定一個(gè)CookieContainer對象,代碼如下:
service.loginService ls = new service.loginService();
System.Net.CookieContainer cc = new System.Net.CookieContainer();
ls.CookieContainer = cc;
bool r, rs;
ls.login("bill", "1234", out @r, out rs);
if (r)
{
MessageBox.Show(ls.getLoginMsg().@return);
}
如果是訪問跨服務(wù)的支持會(huì)話的WebService,則不需要指定CookieContainer對象,代碼如下:
service.loginService ls = new service.loginService();
bool r, rs;
ls.login("bill", "1234", out @r, out rs);
if (r)
{
service1.searchService ss = new service1.searchService();
MessageBox.Show(ss.findByName("abc"));
}
如果讀者使用delphi(本文使用的是delphi2009,其他的delphi版本請讀者自行測試)調(diào)用支持會(huì)話的WebService時(shí)有一些差別。經(jīng)筆者測試,使用delphi調(diào)用WebService,將scope屬性值設(shè)為transportsession和application都可以實(shí)現(xiàn)跨服務(wù)的會(huì)話管理,這一點(diǎn)和Java與C#不同,Java和C#必須將scope屬性值設(shè)為application才支持跨服務(wù)會(huì)話管理。在delphi中不需要象C#指定一個(gè)CookieContainer或其他類似的對象,而只需要象訪問普通的WebService一樣訪問支持會(huì)話的WebService即可。
下一篇:WebService大講堂之Axis2(7):將Spring的裝配JavaBean發(fā)布成WebService
新浪微博:http://t.sina.com.cn/androidguy 昵稱:李寧_Lining