在《Axis2 系列教程(五):會話管理》中介紹了單一服務內的 Session 管理。但在實際企業級應用中,系統通常包含多個 Web Service(如用戶認證服務、業務處理服務),這時便需要在不同服務間共享會話狀態,即所謂的「跨服務會話管理」。本文將詳細說明實現步驟並提供完整範例。
跨服務 Session 需完成三個關鍵步驟:
MessageContext 與 ServiceGroupContext 存取 Key-Value 對。services.xml 中為參與會話的 <service> 元素加上 scope="application" 屬性。setManageSession(true) 啟用會話管理(與單服務模式相同)。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)) {
MessageContext mc = MessageContext.getCurrentMessageContext();
ServiceGroupContext sgc = mc.getServiceGroupContext();
sgc.setProperty("login", "成功登錄");
return true;
}
return false;
}
public String getLoginMsg() {
MessageContext mc = MessageContext.getCurrentMessageContext();
ServiceGroupContext sgc = mc.getServiceGroupContext();
return (String) sgc.getProperty("login");
}
}
package service;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.context.ServiceGroupContext;
public class SearchService {
public String findByName(String name) {
MessageContext mc = MessageContext.getCurrentMessageContext();
ServiceGroupContext sgc = mc.getServiceGroupContext();
if (sgc.getProperty("login") != null)
return "找到的數據<" + name + ">";
else
return "用戶未登錄";
}
}
將兩個服務包裹在 <serviceGroup> 中,並分別設定 scope="application":
<serviceGroup>
<service name="loginService" scope="application">
<description> 登錄服務 </description>
<parameter name="ServiceClass"> service.LoginService </parameter>
<messageReceivers>
<messageReceiver mep="https://www.w3.org/2004/08/wsdl/in-out"
class="org.apache.axis2.rpc.receivers.RPCMessageReceiver" />
</messageReceivers>
</service>
<service name="searchService" scope="application">
<description> 搜索服務 </description>
<parameter name="ServiceClass"> service.SearchService </parameter>
<messageReceivers>
<messageReceiver mep="https://www.w3.org/2004/08/wsdl/in-out"
class="org.apache.axis2.rpc.receivers.RPCMessageReceiver" />
</messageReceivers>
</service>
</serviceGroup>
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);
}
執行結果:
成功登錄
找到的數據<abc>
CookieContainer,直接實例化各服務 Proxy 即可共享 Session。scope 設為 transportsession 或 application 均可實現跨服務會話,且無需手動管理 Cookie,行為與 Java/C# 不同。Axis2 的會話管理底層同樣基於 Cookie。單服務會話使用 ServiceContext(對應 transportsession),跨服務會話則升級至 ServiceGroupContext(對應 application),使同一服務群組內的所有服務共享同一會話上下文。