跳到导航
dev2dev.bea.com.cn
首页 资源中心 dev2dev学堂 在线技术论坛 专家Blog User Group CodeShare
dev2dev 首页 > 资源中心 > 专家Blog > 专家Blog文章
访问 Workshop 会话式 WebServices

时间:2005-04-13
作者:Dmitri Maximovich
浏览次数:
本文关键字:
文章工具
推荐给朋友 推荐给朋友
打印文章 打印文章
访问Workshop 会话式 WebServices

BEA Workshop 为创建两类 WebService 提供了便利,这两类 WebService 是:

  • 无状态:两次方法调用之间不保存状态
  • 会话式:WebServices 在两次方法调用间记录并保持状态

对于 WebService 客户机,调用无状态服务的方法非常简单,而对于会话式服务则需要更为复杂的交互。

在这里,我将为您展示在线Conversational WebService 是如何工作的。

会话阶段

Webservices 通过使用会话阶段注释(conversation-phase annotation)标记特定的方法以转变成对话式服务。扼要地说,下图显示了具有标记开始、继续和结束方法的WebService。

ConversationalWebServices.png

ConversationID

使用标准Servlet,HTTP 会话状态被记录在服务器上,并且可以通过提供会话令牌的客户机访问。会话式 WebServices 也是用同样的方法,不过会话令牌称为conversationID。

会话令牌和 conversationID 的主要区别在于后者由客户机负责生成。converationID 可以是数字和字母的任意组合。

Conversational SOAP 头

ConversationID 不是调用的一部分,而是为 WebService 运行时提供上下文信息,从这个意义上可以将其看作当前方法调用的“元数据”。因此ConversationID 在Conversational Header 中传递,会话头在SOAP Envelope Header 中传输。

访问 WebService 使用两种不同的会话头格式:

  • StartHeader——这种头只用于调用使用开始会话阶段标记的方法,形式如下:
<ns1:StartHeader xmlns:ns1="http://www.openuri.org/2002/04/soap/conversation/">
   <conversationID>123456789/conversationID>
   <callbackURL>http://localhost/myCallbacks</callbackURL>
</ns1:StartHeader>
	

回调URL(callback URL)用于告诉Webservice 运行时Conversational Callback 发送到何处。本文不讨论回调,关于使用回调的更多信息请参阅BEA Workshop 文档。

  • Continue Header——这种头用于调用所有的后续会话方法,形式为:
<ns1:ContinueHeader xmlns:ns1="http://www.openuri.org/2002/04/soap/conversation/">
    <conversationID>123456789</conversationID>
</ns1:ContinueHeader>

具体的例子

下面的例子来自Apache Axis TCP Monitor,说明上述头部在实际调用中的情况。

调用标记为 Start 的方法

<?xml version="1.0" encoding="utf-8"?>
<SOAP-ENV:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                                             xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                                             xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
   <SOAP-ENV:Header>
      <ns1:StartHeader xmlns:ns1="http://www.openuri.org/2002/04/soap/conversation/">
         <conversationID>1234567892</conversationID>
         <callbackURL>http://localhost/myCallbacks</callbackURL>
      </ns1:StartHeader>
   </SOAP-ENV:Header>
   <SOAP-ENV:Body>
      <StartMethod xmlns="http://www.openuri.org/">
          <name>Dave</name>
      </StartMethod>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

调用标记为Continue的方法

<?xml version="1.0" encoding="utf-8"?>
<SOAP-ENV:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                                             xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                                             xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
   <SOAP-ENV:Header>
      <ns1:ContinueHeader xmlns:ns1="http://www.openuri.org/2002/04/soap/conversation/">
         <conversationID>1234567892</conversationID>
      </ns1:ContinueHeader>
   </SOAP-ENV:Header>
   <SOAP-ENV:Body>
      <ContinueMethod xmlns="http://www.openuri.org/" />
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

WSDL

WebService 客户机通过服务 WSDL 文档发现头部的存在和形式。下面是摘自一个会话式服务 WSDL 文档的 Header 模式:

<s:schema elementFormDefault="qualified" targetNamespace="http://www.openuri.org/2002/04/soap/conversation/">
  <s:element name="StartHeader" type="conv:StartHeader"/>
  <s:element name="ContinueHeader" type="conv:ContinueHeader"/>
  <s:element name="CallbackHeader" type="conv:CallbackHeader"/>
  <s:complexType name="StartHeader">
    <s:sequence>

      <s:element minOccurs="0" maxOccurs="1" name="conversationID" type="s:string"/>
      <s:element minOccurs="0" maxOccurs="1" name="callbackLocation" type="s:string"/>
    </s:sequence>
  </s:complexType>
  <s:complexType name="ContinueHeader">
    <s:sequence>
      <s:element minOccurs="1" maxOccurs="1" name="conversationID" type="s:string"/>
    </s:sequence>
  </s:complexType>
  <s:complexType name="CallbackHeader">
    <s:sequence>
      <s:element minOccurs="1" maxOccurs="1" name="conversationID" type="s:string"/>
    </s:sequence>
  </s:complexType>
</s:schema>

上面定义的Callback 头用于在调用回调方法的过程中向调用客户机传回conversationID。

WSDL 扩展

如果从Converstional WebService WSDL 文档创建WebService 控件,该控件可以决定每个方法的会话阶段。

为此文档中内嵌了专门的转换扩展。下面的例子给出了一个用这种“cw:transition"”扩展标记的方法。

注意:xmlns:cw="http://www.openuri.org/2002/04/wsdl/conversation/"

converstational-phase:start

<operation name="StartMethod">
  <soap:operation soapAction="http://www.openuri.org/StartMethod" style="document"/>
  <cw:transition phase="start"/>
  <input>
    <soap:body use="literal"/>
    <soap:header xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
                                  wsdl:required="true"
                                  message="s0:StartHeader_literal"
                                  part="StartHeader"
                                  use="literal"/>
  </input>
  <output>
    <soap:body use="literal"/>
  </output>
</operation>

converstational-phase:continue

<operation name="continueMethod">
  <soap:operation soapAction="http://www.openuri.org/continueMethod" style="document"/>
  <cw:transition phase="continue"/>
  <input>
    <soap:body use="literal"/>
    <soap:header xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
                                  wsdl:required="true"
                                  message="s0:ContinueHeader_literal"
                                  part="ContinueHeader"
                                  use="literal"/>
  </input>
  <output>
    <soap:body use="literal"/>
  </output>
</operation>

从 Weblogic WebService 客户机访问

如果使用标准的 Weblogic Webservice 客户机库,不需要添加这些会话头。这是因为客户机库能够识别这种 WSDL 扩展,为调用附加适当的头。客户机库还生成converationID,并在调用继续方法的时候重用。

但有时候可能希望明确规定在调用中指定conversationID。为此,必须使用一个未公布的 API 并在 WebService 上下文中添加conversationID。

下面的代码显示了明确设定 conversationID 的Conversational Service 交互:

package bea.example;

import bea.example.convservice.client.TestConversational_Impl;
import bea.example.convservice.client.TestConversationalSoap;
import bea.example.convservice.client.TestConversational;

// Weblogic Extensions
import weblogic.webservice.context.WebServiceContext;
import weblogic.webservice.context.WebServiceHeader;
import weblogic.webservice.WLMessageContext;

public class ConvClient {

  public static void main(String args[]) throws Exception {

      // Get a copy of the service proxy
      TestConversational service = new TestConversational_Impl();
      TestConversationalSoap client = service.getTestConversationalSoap();

      // Set the conversationID
      WebServiceContext ctx = service.context();
      ctx.getSession().setAttribute(WLMessageContext.CONVERSATION_PROP,"12345678922");

      // Call the start method
      System.out.println(client.startMethod("David Maddison"));

      // Call the continue method
      System.out.println("Continue Reply=" + client.continueMethod());

      // And Clean up
      System.out.println("Finish Reply=" + client.finishMethod());
  }
}

 

 

为了完整起见,上述客户机通信的WebService 在下面给出:

public class TestConversational implements com.bea.jws.WebService

    static final long serialVersionUID = 1L;

    String _name;

    /**
     * @common:operation
     * @jws:conversation phase="start"
     */
    public String StartMethod(String name)
    {
        _name = name;
        
        return "Hello From Start Method";
    }

    /**
     * @common:operation
     * @jws:conversation phase="continue"
     */
    public String ContinueMethod()
    {
        return _name;
    }

    /**
     * @common:operation
     * @jws:conversation phase="finish"
     */
    public String FinishMethod()
    {
        return "Conversation Ending!";
    }

原文出处:http://dev2dev.bea.com/blog/maddison/archive/2005/04/accessing_works_1.html

dot dot dot

dot
  作者其它文章
您对本文的评价
您对这篇文章的看法如何?
太棒了!5分 不错啊 4分 一般般 3分 有待提高 2分 不好 1分