在Web service中通常采用兩種公認技術來管理session,一種是借助HTTP和HTTP cookies,另一種是用SOAP headers。Axis能幫你實現這兩種技術。
by Kevin Jones
在Web service中沒有一種管理session的標準方法,只有兩種公認的技術,一種是依靠HTTP和HTTP cookies,另一種,或許也是最重要的一種方法,就是用SOAP headers。Axis能幫助開發人員實現這兩種技術。
在Axis中缺省使用的是HTTP managed sessions。在一個服務器中這么做是十分容易的,因為大多數對Axis Web service的管理是通過org.apache.axis.MessageContext的一個實例來完成的。在一個Axis Web service中你可以通過調用MessageContext類中的靜態方法來得到MessageContext的一個實例:
public class SessionService { public String echo(String in) { MessageContext mc = MessageContext.getCurrentContext(); |
MessageContext中有一個名為setMaintainSession的方法,調用它便可激活session。但在編寫(Axis 1.1 RC2)時,session對象只有在被訪問時才能激活,如下列代碼所示:
public class SessionService { public String echo(String in) { MessageContext mc = MessageContext. getCurrentContext(); Session session = mc.getSession(); String name = (String)session.get("name"); return in; } } |
這樣會導致Axis架構生成一個set-cookie header:
Set-Cookie: JSESSIONID=49EBBB19A1B2F8D10EE075F6F14CB8C9; Path=/axissessions |
客戶端需要在Cookie header中返回這個Cookie來保持該session。為了使axis運行狀態下的客戶端能夠實現這一點,就必須調用org.apache.axis.client.Service接口的setMaintainSession方法。該接口是由WSDL2Java生成工具所生成的Locator類實現的。調用該方法之后,Axis架構會自動將該cookie返回到服務器中:
public static void main(String[] args) { UseSessionsServiceLocator locator = new UseSessionsServiceLocator(); locator.setMaintainSession(true); |
header看起來就像這樣:
Cookie: JSESSIONID=49EBBB19A1B2F8D10EE075F6F14CB8C9 |
通過HTTP傳輸cookie是沒有問題的,但如果客戶端或服務器不通過HTTP,或使用的是通過多個Web services傳入調用的multihop service,那么這種方法就不那么有效了。一種更好的方法是用SOAP headers來加載session id。
Axis架構支持多個Handlers。通過在一個Web service請求過程中調用調棧(call stack),Handlers能夠被放置到很多地方,它可以和傳輸過程結合起來,或者和一個Web service一起使用。Handlers可以被插入其中來處理Web service請求中的請求和/或響應語句。
Axis帶有一個名為org.apache.axis.handlers.SimpleSessionHandler的handler,它用于提供基于session管理的SOAP header。要使用這個簡單的帶有Web service的session handler,你必須告知Axis架構將該handler添加到handler鏈中。你可以通過將該handler信息添加到server-config.wsdd來實現這一點;一個簡單的處理方法是定義一個包含額外配置Web service所需的WSDD文件,然后用Axis部署工具來部署這個配置文件。
這個WSDD文件看起來就像這樣:
<deployment xmlns= "http://xml.apache.org/axis/wsdd/" xmlns:java= "http://xml.apache.org/axis/wsdd/ providers/java"> <handler name="session" type="java:org.apache.axis.handlers. SimpleSessionHandler"/> <service name="Sessions" provider= "java:RPC" style="wrapped"> <namespace>urn:kevinj:Sessions</namespace> <requestFlow> <handler type="session"/> </requestFlow> <responseFlow> <handler type="session"/> </responseFlow> <parameter name="className" value= "kevinj.UseSessions"/> <parameter name="allowedMethods" value="*"/> </service> </deployment> |
該handler是和service分開定義并引用的,雖然你可以在service內部定義它。注意這個handler是同時為了請求和響應而定義的;這就確保了這些headers能夠在請求中被讀取并添加到響應中去。你可以用這個管理工具來部署它:
java -cp [classpath to axis bits here] / org.apache.axis.client.AdminClient / -lhttp://localhost/myservice/AxisServlet deploy.wsdd |
現在服務器就可以運行了,在使用該handler時服務器無需處理任何事情;而headers能夠自動被添加進去,就像這樣:
<soapenv:Header> <ns1:sessionID soapenv:actor="" soapenv:mustUnderstand="0" xsi:type="xsd:long" xmlns:ns1= "http://xml.apache.org/axis/ session"> -1919645576528915916 </ns1:sessionID> </soapenv:Header> |
要使用這個header,Web service客戶端必須能夠讀取它并了解其語法;而Axis客戶端可以解決這個問題。
要創建一個使用這個簡單session的Axis客戶端,你需要配置Axis客戶端框架來使用該handler。過程同服務器端很相似,但不是部署到服務器,而是在本地創建config文件。你可以通過運行org.apache.axis.utils.Admin來實現這一點。運行以下代碼:
org.apache.axis.utils.Admin client deploy.wsdd |
這樣就創建了一個client-config.wsdd文件,它同樣也包含handler代碼。
<?xml version="1.0" encoding="UTF-8"?> <deployment xmlns= "http://xml.apache.org/axis/wsdd/" xmlns:java= "http://xml.apache.org/axis/ wsdd/providers/java"> <globalConfiguration> <parameter name="adminPassword" value="admin"/> <parameter name="attachments.implementation" value= "org.apache.axis.attachments. AttachmentsImpl"/> <parameter name= "sendMultiRefs" value="true"/> <parameter name="sendXsiTypes" value= "true"/> <parameter name= "sendXMLDeclaration" value="true"/> <parameter name="axis.sendMinimizedElements" value="true"/> <requestFlow> <handler type= "java:org.apache.axis.handlers. SimpleSessionHandler"/> </requestFlow> <responseFlow> <handler type= "java:org.apache.axis.handlers. SimpleSessionHandler"/> </responseFlow> </globalConfiguration> <handler name="session" type= "java:org.apache.axis.handlers. SimpleSessionHandler"/> <service name="Sessions" provider= "java:RPC" style="wrapped" use="literal"> <requestFlow> <handler type="session"/> </requestFlow> <responseFlow> <handler type="session"/> </responseFlow> <parameter name="allowedMethods" value="*"/> <parameter name="className" value= "kevinj.UseSessions"/> <namespace>urn:kevinj:Sessions</namespace> </service> <transport name="java" pivot= "java:org.apache.axis.transport. java.JavaSender"/> <transport name="http" pivot= "java:org.apache.axis.transport. http.HTTPSender"/> <transport name="local" pivot= "java:org.apache.axis.transport. local.LocalSender"/> </deployment> |
為了使客戶端能夠利用這個handler,你必須將client-config.wsdd文件添加到客戶端的classpath中。然后由Axis框架代表客戶端來讀取并響應這些headers。同樣,客戶端代碼無需處理任何事情便可以使用它了。
關于作者:
Kevin Jones是一名有著15年開發經驗的開發人員。最近四年來,他一直從事Java編程方面的研究和教學,最近, 他主要研究HTTP和XML。Kevin住在U.K.,他為Developmentor工作,這是一家以United States 和Europe為基地,主要做Java和Microsoft平臺的技術培訓的公司。Kevin的聯系方式是:kevinj@develop.com。