楼主: lastwinner

[转载] 使用 AJAX 调用 SOAP Web 服务

[复制链接]
论坛徽章:
484
ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:02ITPUB北京九华山庄2008年会纪念徽章
日期:2008-01-21 16:50:24ITPUB北京2009年会纪念徽章
日期:2009-02-09 11:42:452010新春纪念徽章
日期:2010-03-01 11:04:552010数据库技术大会纪念徽章
日期:2010-05-13 10:04:272010系统架构师大会纪念
日期:2010-09-04 13:35:54ITPUB9周年纪念徽章
日期:2010-10-08 09:28:512011新春纪念徽章
日期:2011-02-18 11:43:32ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:54
11#
 楼主| 发表于 2006-7-8 00:00 | 只看该作者
清单 4 显示了由 清单 3 中的代码生成的 SOAP 信封。
清单 4. 构建一个 SOAP 信封
[php]
<Envelope xmlns="http://schemas.xmlsoap.org">
  <Body>
    <method xmlns="urn:foo">
      <param>bar</param>
    </method>
  </Body>
</Envelope>

........
[/php]

使用道具 举报

回复
论坛徽章:
484
ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:02ITPUB北京九华山庄2008年会纪念徽章
日期:2008-01-21 16:50:24ITPUB北京2009年会纪念徽章
日期:2009-02-09 11:42:452010新春纪念徽章
日期:2010-03-01 11:04:552010数据库技术大会纪念徽章
日期:2010-05-13 10:04:272010系统架构师大会纪念
日期:2010-09-04 13:35:54ITPUB9周年纪念徽章
日期:2010-10-08 09:28:512011新春纪念徽章
日期:2011-02-18 11:43:32ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:54
12#
 楼主| 发表于 2006-7-8 01:04 | 只看该作者
如果您正在创建的 SOAP 信封代表一个 RPC 样式的请求,则 SOAP.Body 元素提供了一个简便方法 set_rpc(如清单 5 所示),该方法能够构造一个完整的 RPC 请求——包含一个指定的操作名称、一个指定的输入参数数组和一个 SOAP 编码样式的 URI。
清单 5. 构建一个 RPC 请求信封
[php]
var envelope = new SOAP.Envelope();
var body = envelope.create_body();
body.set_rpc(
  new WS.QName('param','urn:foo'),
  new Array(
    {name:'param',value:'bar'}
  ), SOAP.NOENCODING
);

[/php]

使用道具 举报

回复
论坛徽章:
484
ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:02ITPUB北京九华山庄2008年会纪念徽章
日期:2008-01-21 16:50:24ITPUB北京2009年会纪念徽章
日期:2009-02-09 11:42:452010新春纪念徽章
日期:2010-03-01 11:04:552010数据库技术大会纪念徽章
日期:2010-05-13 10:04:272010系统架构师大会纪念
日期:2010-09-04 13:35:54ITPUB9周年纪念徽章
日期:2010-10-08 09:28:512011新春纪念徽章
日期:2011-02-18 11:43:32ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:54
13#
 楼主| 发表于 2006-7-8 01:04 | 只看该作者
每个参数都作为一个 JavaScript 对象结构进行传递,且可能带有以下属性:
  • name。一个指定参数名称的字符串或 WS.QName 对象。必需
  • value。参数的值。如果该值不是一个简单数据类型(例如,字符串、整数或其他),则应该指定一个能将该值序列化为适当的 XML 结构的 WS.Binder。必需
  • xsitype:标识参数的 XML 模式实例类型的 WS.QName(例如,xsi:type="int" 对应 xsitype:new WS.QName('int','http://www.w3.org/2000/10/XMLSchema'))。可选
  • encodingstyle:标识参数所使用的 SOAP 编码样式的 URI。可选
  • binder:能够将参数序列化为 XML 的 WS.Binder 实现。可选

例如,如果要指定的参数名为“abc”、XML 命名空间为“urn:foo”、xsi:type 为“int”且值为“3”,则我会使用以下代码:new Array({name:new WS.QName('abc','urn:foo'), value:3, xsitype:new WS.QName('int','http://www.w3.org/2000/10/XMLSchema')})。
一旦我为服务请求构建了 SOAP.Envelope,我就会将该 SOAP.Envelope 传递到 WS.Call 对象的 invoke 方法,以便调用该信封内编码的方法: (new WS.Call(service_uri)).invoke(envelope, callback)

使用道具 举报

回复
论坛徽章:
484
ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:02ITPUB北京九华山庄2008年会纪念徽章
日期:2008-01-21 16:50:24ITPUB北京2009年会纪念徽章
日期:2009-02-09 11:42:452010新春纪念徽章
日期:2010-03-01 11:04:552010数据库技术大会纪念徽章
日期:2010-05-13 10:04:272010系统架构师大会纪念
日期:2010-09-04 13:35:54ITPUB9周年纪念徽章
日期:2010-10-08 09:28:512011新春纪念徽章
日期:2011-02-18 11:43:32ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:54
14#
 楼主| 发表于 2006-7-8 01:05 | 只看该作者
另一种可选方案是手动构建 SOAP.Envelope。我会将参数 WS.QName、参数数组和编码样式传递到 WS.Call 对象的 invoke_rpc 方法,如清单 6 所示。
清单 6. 使用 WS.Call 对象调用 Web 服务
[php]
var call = new WS.Call(serviceURI);
var nsuri = 'urn:foo';
var qn_op = new WS.QName('method',nsuri);
var qn_op_resp = new WS.QName('methodResponse',nsuri);  
  call.invoke_rpc(
    qn_op,
    new Array(
      {name:'param',value:'bar'}
    ),SOAP.NOENCODING,
    function(call,envelope) {
      // envelope is the response SOAP.Envelope
      // the XML Text of the response is in arguments[2]
    }
  );

[/php]

在调用 invoke 方法或 invoke_rpc 方法时,WS.Call 对象会创建一个基本的 XMLHttpRequest 对象,用包含 SOAP 信封的 XML 元素进行传递,并接收和解析响应,然后调用提供的回调函数。

使用道具 举报

回复
论坛徽章:
484
ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:02ITPUB北京九华山庄2008年会纪念徽章
日期:2008-01-21 16:50:24ITPUB北京2009年会纪念徽章
日期:2009-02-09 11:42:452010新春纪念徽章
日期:2010-03-01 11:04:552010数据库技术大会纪念徽章
日期:2010-05-13 10:04:272010系统架构师大会纪念
日期:2010-09-04 13:35:54ITPUB9周年纪念徽章
日期:2010-10-08 09:28:512011新春纪念徽章
日期:2011-02-18 11:43:32ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:54
15#
 楼主| 发表于 2006-7-8 01:06 | 只看该作者
为了能够扩展 SOAP 消息的预处理和后处理,WS.Call 对象允许您注册一组 WS.Handler 对象,如清单 7 所示。对于调用周期内的每个请求、每个响应和每个错误,都将调用这些对象。可以通过扩展 WS.Handler JavaScript 对象来实现新的处理程序。
清单 7. 创建和注册响应/响应处理程序
[php]var MyHandler = Class.create();
MyHandler.prototype = (new WS.Handler()).extend({
  on_request : function(envelope) {
     // pre-request processing
  },
  on_response : function(call,envelope) {
     // post-response, pre-callback processing
  },
  on_error : function(call,envelope) {
  }
});

var call = new WS.Call(...);
call.add_handler(new MyHandler());

........
[/php]

使用道具 举报

回复
论坛徽章:
484
ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:02ITPUB北京九华山庄2008年会纪念徽章
日期:2008-01-21 16:50:24ITPUB北京2009年会纪念徽章
日期:2009-02-09 11:42:452010新春纪念徽章
日期:2010-03-01 11:04:552010数据库技术大会纪念徽章
日期:2010-05-13 10:04:272010系统架构师大会纪念
日期:2010-09-04 13:35:54ITPUB9周年纪念徽章
日期:2010-10-08 09:28:512011新春纪念徽章
日期:2011-02-18 11:43:32ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:54
16#
 楼主| 发表于 2006-7-8 01:07 | 只看该作者
处理程序对插入或提取正在传递的 SOAP 信封中的信息最有用。例如,您可以设想一个处理程序自动向 SOAP Envelope 的 Header 插入适当的 Web 服务寻址 (Web Services Addressing) 元素,如清单 8 中的示例所示。
清单 8. 一个将 Web 服务寻址操作 Header 添加到请求中的处理程序示例
[php]
var WSAddressingHandler = Class.create();
WSAddressingHandler.prototype = (new WS.Handler()).extend({
  on_request : function(call,envelope) {                 
    envelope.create_header().create_child(
        new WS.QName('Action','http://ws-addressing','wsa')
      ).set_value('http://www.example.com');
  }
});
...
[/php]

使用道具 举报

回复
论坛徽章:
484
ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:02ITPUB北京九华山庄2008年会纪念徽章
日期:2008-01-21 16:50:24ITPUB北京2009年会纪念徽章
日期:2009-02-09 11:42:452010新春纪念徽章
日期:2010-03-01 11:04:552010数据库技术大会纪念徽章
日期:2010-05-13 10:04:272010系统架构师大会纪念
日期:2010-09-04 13:35:54ITPUB9周年纪念徽章
日期:2010-10-08 09:28:512011新春纪念徽章
日期:2011-02-18 11:43:32ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:54
17#
 楼主| 发表于 2006-7-8 01:11 | 只看该作者
WS.Binder 对象(清单 9)执行 SOAP.Element 对象的自定义序列化和反序列化。WS.Binder 的实现必须提供以下两个方法:
  • to_soap_element。将 JavaScript 对象序列化为 SOAP.Element。传入的第一个参数是要序列化的值。第二个参数是 SOAP.Element,必须将要序列化的值序列化为 SOAP.Element。该方法不返回任何值。
  • to_value_object。将 SOAP.Element 反序列化为 JavaScript 对象。该方法必须返回反序列化的值对象。

清单 9. WS.Binding 实现示例
[php]
var MyBinding = Class.create();
MyBinding.prototype = (new WS.Binding()).extend({
  to_soap_element : function(value,element) {                 
    ...
  },
  to_value_object : function(element) {
    ...
  }
});
[/php]

使用道具 举报

回复
论坛徽章:
484
ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:02ITPUB北京九华山庄2008年会纪念徽章
日期:2008-01-21 16:50:24ITPUB北京2009年会纪念徽章
日期:2009-02-09 11:42:452010新春纪念徽章
日期:2010-03-01 11:04:552010数据库技术大会纪念徽章
日期:2010-05-13 10:04:272010系统架构师大会纪念
日期:2010-09-04 13:35:54ITPUB9周年纪念徽章
日期:2010-10-08 09:28:512011新春纪念徽章
日期:2011-02-18 11:43:32ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:54
18#
 楼主| 发表于 2006-7-8 23:41 | 只看该作者
一个简单示例

我已经提供了一个示例项目来阐释 Web Services JavaScript Library 的基本功能。该演示所使用的 Web 服务(如清单 10 所示)已经在 WebSphere Application Server 中进行了实现,并提供了简单的 Hello World 功能。


清单 10. 一个简单的基于 Java 的“Hello World”Web 服务

                                [php]
package example;

public class HelloWorld {
  public String sayHello(String name) {
    return "Hello " + name;
  }
}

[/php]

使用道具 举报

回复
论坛徽章:
484
ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:02ITPUB北京九华山庄2008年会纪念徽章
日期:2008-01-21 16:50:24ITPUB北京2009年会纪念徽章
日期:2009-02-09 11:42:452010新春纪念徽章
日期:2010-03-01 11:04:552010数据库技术大会纪念徽章
日期:2010-05-13 10:04:272010系统架构师大会纪念
日期:2010-09-04 13:35:54ITPUB9周年纪念徽章
日期:2010-10-08 09:28:512011新春纪念徽章
日期:2011-02-18 11:43:32ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:54
19#
 楼主| 发表于 2006-7-8 23:41 | 只看该作者
在实现了该服务并将其部署到 WebSphere Application Server 后,该服务(清单 11)的 WSDL 描述定义了您需要传递的 SOAP 消息(用于调用 Hello World 服务)。


清单 11. HelloWorld.wsdl 的代码片段
[php]
                               
<wsdlortType name="HelloWorld">
  <wsdlperation name="sayHello">
    <wsdl:input
      message="impl:sayHelloRequest"
      name="sayHelloRequest"/>
    <wsdlutput
      message="impl:sayHelloResponse"
      name="sayHelloResponse"/>
  </wsdlperation>
</wsdlortType>

[/php]

使用道具 举报

回复
论坛徽章:
484
ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:02ITPUB北京九华山庄2008年会纪念徽章
日期:2008-01-21 16:50:24ITPUB北京2009年会纪念徽章
日期:2009-02-09 11:42:452010新春纪念徽章
日期:2010-03-01 11:04:552010数据库技术大会纪念徽章
日期:2010-05-13 10:04:272010系统架构师大会纪念
日期:2010-09-04 13:35:54ITPUB9周年纪念徽章
日期:2010-10-08 09:28:512011新春纪念徽章
日期:2011-02-18 11:43:32ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:54
20#
 楼主| 发表于 2006-7-8 23:42 | 只看该作者
通过使用 Web Services JavaScript Library,您可以实现一个调用 Hello World 服务的方法,如清单 12所示。


清单 12. 使用 WS.Call 调用 HelloWorld 服务

                                [php]
<html>
<head>
...
<script
  type="text/javascript"
  src="scripts/prototype.js"></script>
<script
  type="text/javascript"
  src="scripts/ws.js"></script>
<script type="text/javascript">
function sayHello(name, container) {
  var call = new WS.Call('/AjaxWS/services/HelloWorld');
  var nsuri = 'http://example';
  var qn_op = new WS.QName('sayHello',nsuri);
  var qn_op_resp = new WS.QName('sayHelloResponse',nsuri);  
  call.invoke_rpc(
    qn_op,
    new Array(
      {name:'name',value:name}
    ),null,
    function(call,envelope) {
      var ret =
        envelope.get_body().get_all_children()[0].
          get_all_children()[0].get_value();
      container.innerHTML = ret;
      $('soap').innerHTML = arguments[2].escapeHTML();
    }
  );
}
</script>
</head>
...
.......................
[/php]

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表