AngularJS - 与 AngularJS 模型的 SOAP 服务集成

Posted

技术标签:

【中文标题】AngularJS - 与 AngularJS 模型的 SOAP 服务集成【英文标题】:AngularJS - SOAP Service Integration With AngularJS Model 【发布时间】:2013-07-03 15:37:51 【问题描述】:

我是一名经验丰富的 Flex 开发人员,正在学习 AngularJS。这太混乱了!!!

无论如何,我正在尝试通过 SOAP WSDL 请求对我的后端(在同一域上)服务器进行服务调用,并使用 AngularJS 模型对象填充数据。我正在尝试 Ajax,但在获取实际数据时遇到了一些问题。我认为我创建 SOAP 标记的方式有问题。我得到了成功的回复,但没有数据。

在搞不懂 Ajax 方法后,我偶然发现了 soapclient.js,发现它非常简单,代码比 Ajax 少。 soapclient.js 为您完成了大部分工作,类似于 Ajax 方法,这使得代码更少。此外,使用soapclient.js,我可以进行SOAP调用,还可以将数据返回到XML格式的响应中。

http://javascriptsoapclient.codeplex.com

我的问题是我正在尝试使用 AngularJS 将 XML 响应转储到 AnularJS 模型对象中。我不确定如何为我正在做的事情设置 AngularJS 项目,但我真的很想知道最好的方法,以保持我正在做的事情的解耦。我一直在疯狂地搜索 Google,但大多数示例对于初学者来说似乎过于复杂。

这是我所拥有的:

<html>
<head>
    <script language="JavaScript" type="text/javascript" src="jquery-1.10.1.js"></script>
    <script language="JavaScript" type="text/javascript" src="soapclient.js"></script>

    <script type="text/javascript">
        function getData() 
            var url2 = "https://myService";
            var pl = new SOAPClientParameters();

            pl.add("arg0", false);

            SOAPClient.invoke(url2, "methodToCall", pl, true, getDataCallback);
        

        function getDataCallback(r, soapResponse) 
            alert(r.contents.payeeMailName);
        
    </script>
</head>

<body>
<form>
    <input type="button" value="Click Here to Call Web Service" onClick="getData()" style="width: 192px">
</form>
<div id="result">Result?</div>
</body>
</html>

现在,SOAP 服务返回如下数据:

 <return>
    <contents>
       <eftAcctType>S</eftAcctType>
       <id>
          <djNumber>201-16-39063</djNumber>
          <djSequence>1</djSequence>
       </id>
       <payeeAddrLine1>124 Agate Drive</payeeAddrLine1>
    </contents>
    <contents>
       <eftAcctType/>
       <id>
          <djNumber>201-16-39201</djNumber>
          <djSequence>1</djSequence>
       </id>
       <payeeAddrLine1>c/o Kevin Martinez, Attorney at Law</payeeAddrLine1>
    </contents>
    <contents>
       <eftAcctType>C</eftAcctType>
       <id>
          <djNumber>201-16-38561</djNumber>
          <djSequence>1</djSequence>
       </id>
       <payeeAddrLine1>1360 South Highway 191</payeeAddrLine1>
    </contents>
    <status>0</status>
 </return>

什么是AngularJS中进行服务调用的“正确”方式,假设我这样做的方式没问题,如果不是让我知道最好的方式,然后在结果中,我如何循环遍历数据XML 响应并将其解析为 Angular 模型对象?我最终想在 DataGrid 中使用这些数据。

任何帮助将不胜感激。

【问题讨论】:

【参考方案1】:

我想最好的方法是将其实现为$http interceptor。我在我们的项目中这样做了,效果很好,因为角度 $http 调用保持不变。

这是我为我们的项目创建的提供商的链接:http://jsfiddle.net/gqp9m/ 我从soapclient 库中复制粘贴了一些内容,并将其移至提供程序中。我还更改了一些语法,因此代码将通过 jsHint。大多数修改后的功能都用文档注释进行了注释。它还需要 jQuery(对于 $.parseXML 函数 - 您可以重构它以删除 jQuery 中的依赖项)。

最大的不同是我的代码不会在第一次请求时加载 wsdl,而是需要您在进行任何调用之前对其进行缓存,如下所示:

myModule.service(['myModule.soap-interceptor', function(soap)
    $http.get('http://www.myveryfakedomain.com/CRMAPIWS74?wsdl', 
     isJSON: true ).then(function(result)
        soap.setWSDL('http:/www.myveryfakedomain.com/CRMAPIWS74', result.data);
    );
]);

soap 是注入的 soap-interceptor 实例。您调用 wsdl,然后调用 soap.setWSDL,将基本 url 和解析的 wsdl 传递给它。还要注意传递给 $http 调用的 isJSON 参数。这是因为默认情况下我的代码将每个调用都视为 SOAP 请求。这就是拦截器所做的。 isJSON:true 将允许您按照上帝的意图使用 $http ;)

在调用 setWSDL 之后,只需像往常一样调用 $http:

$http.get('http:/www.myveryfakedomain.com/CRMAPIWS74/action').then(function(result)
    // do something...
);

请记住,此代码是为我们的项目编写的,它不是受支持的开源项目或其他东西。在您使用它之前,它可能需要进行一定程度的维护或重构,但这是一个好的开始。

【讨论】:

谢谢。很难,但我从肥皂服务器上得到了一个 wsdl。如何在其中运行命令 getPrice()? &lt;wsdl:message name="getPriceRequest"&gt; &lt;wsdl:part name="symbol" type="xsd:string"/&gt; &lt;/wsdl:message&gt; &lt;wsdl:message name="getPriceResponse"&gt; &lt;wsdl:part name="return" type="xsd:float"/&gt; &lt;/wsdl:message&gt; 我不是 SOAP 专家,我更喜欢 javascript,但您通常通过引用 SOAP 服务的 url 并在末尾添加操作来调用 SOAP 操作 - 像这样:http// www.fakedomain.com/api/getPriceRequest 您使用 POST 执行此操作,并在请求正文中发送 WSDL 中描述的消息。 谢谢。如何通过 SOAP 调用传递数据? 你会碰巧有一个包含这个的小项目吗?我是 AngularJS 的新手,我是一名 Flex 开发人员......在学习 AngularJS 的同时,我试图将这一切拼凑起来。谢谢 抱歉,我的实现是特定于项目的,所以我不能给你一个通用的工作解决方案。关于so​​ap调用中的数据,将请求作为POST发送并在$http options.data中传递soap参数【参考方案2】:

晚了两年,但我已经构建了一个 Angular 模块,专门用于在 GitHub 上使用 SOAP Web 服务。

https://github.com/andrewmcgivery/angular-soap

这是一篇关于如何使用它的博客文章: http://mcgivery.com/soap-web-services-angular-ionic/

长话短说,它允许您执行以下操作:

angular.module('myApp', ['angularSoap'])

.factory("testService", ['$soap',function($soap)
    var base_url = "http://www.cooldomain.com/SoapTest/webservicedemo.asmx";

    return 
        HelloWorld: function()
            return $soap.post(base_url,"HelloWorld");
        
    
])

.controller('MainCtrl', function($scope, testService) 

  testService.HelloWorld().then(function(response)
    $scope.response = response;
  );

)

【讨论】:

这个question中的soap服务器可以工作吗? @Andrew 我在这条线上遇到错误 angular.module('myApp', ['angularSoap']) Error : Uncaught ReferenceError: angular is not defined 您是否在 Angular 脚本之后包含了 Angular 肥皂脚本? 嗨@AndrewMcGivery,有没有办法改变请求xml中的节点前缀?我需要这些前缀 &lt;SOAP-ENV:Envelope&gt;&lt;SOAP-ENV:Body&gt; 而不是当前由您的模块生成的 &lt;soap:Envelope&gt;&lt;soap:Body&gt;。谢谢。 @AndrewMcGivery:我正在使用crcind.com/csp/samples/SOAP.Demo.cls,但遇到了 CORS 问题。【参考方案3】:

您可以在没有任何 SOAP wsdl 库的情况下实现这一点。将您的 wsdl 导入 SOAP UI 并复制信封。下面是 AngularJS 中如何处理 SOAP Web 服务的示例。

服务:

app.service('service', function($http) 
this.soapService = function(_anydata) 
    var _url = 'soap_service_endpoint_url';
    var soapRequest = '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:jn=""><soapenv:Header/><soapenv:Body><=== xxx ===></soapenv:Body></soapenv:Envelope>';
    var soapAction = '<=== soap action ===>';
    var headers = 
        'SOAPAction': soapAction,
        'Content-Type': 'text/xml; charset=utf-8'
    ;
    return $http.post(_url, soapRequest, 
        "headers": headers
    );

);

调用服务并处理 XML 输出。你可以捕获你想要的属性:

service.soapService(data).then(function success(response) 
var _dataArr = [];
$(response.data).find('Transaction').each(function() 
    _dataArr.push(
        name: $(this).find('<=== your attributes ===>').text()
    );
);
return _dataArr;
, function error(response) 
console.log('<==== soap error: ' + response);
return response;
);

【讨论】:

以上是关于AngularJS - 与 AngularJS 模型的 SOAP 服务集成的主要内容,如果未能解决你的问题,请参考以下文章

如何为不同的项目版本和管理 angularjs 组件

一个模块中的 AngularJS 指令和另一个模块中的模板

AngularJS - 与 AngularJS 模型的 SOAP 服务集成

AngularJS

AngularJS 学习笔记

Angularjs 1.6.+ 是不是与 jQuery 3.5+ 兼容?