【问题标题】:SOAP client using perl - WSDL URL is available使用 perl 的 SOAP 客户端 - WSDL URL 可用
【发布时间】:2021-08-09 20:33:33
【问题描述】:

我有一个 powershell 脚本,它将进行一次肥皂调用,并执行以下操作: 1.连接到托管 WSDL 的服务器(在应用程序术语中称为单元) 2.在其中创建一个事件(警报)。 3.与托管 WSDL 的服务器断开连接(在应用程序术语中称为单元) 我想创建这个脚本的 perl 版本.. 它执行相同的操作,请帮助我提供功能和示例。或者如果可能的话,用 perl 重写下面的脚本。 提前非常感谢您:

PS脚本如下:

================================================ =================================

$severity = "MAJOR"

$msg = "Test event from Powershell"
$cellname = "mycell"

$url = "http://iiwshostname:9080/imws/services/ImpactManager/"
$headers = @{ "SOAPAction" = "Connect"}
$soap = [xml]@"
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:imap="http://blueprint.bmc.com/ImapiElems">
   <soapenv:Header/>
   <soapenv:Body>
      <imap:Connect>
         <imap:userName>admin</imap:userName>
         <imap:password>admin</imap:password>
         <imap:imname>$cellname</imap:imname>
         <imap:bufferType>BMCII_BUFFER_MODE_DEFAULT</imap:bufferType>
      </imap:Connect>
   </soapenv:Body>
</soapenv:Envelope>
"@
[xml]$ret = Invoke-WebRequest $url -Method post -ContentType 'text/xml' -Body $soap -Headers $headers
$connectionId = $ret.GetElementsByTagName("imap:connectionId").'#text'

$headers = @{ "SOAPAction" = "SendEvent"}
$soap = [xml]@"
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:imap="http://blueprint.bmc.com/ImapiElems" xmlns:bas="http://blueprint.bmc.com/BasicTypes" xmlns:even="http://blueprint.bmc.com/Event">
   <soapenv:Header/>
   <soapenv:Body>
      <imap:SendEvent>
         <imap:connection>$connectionId</imap:connection>
         <imap:message>    
            <bas:NameValue_element>    
               <bas:name>msg</bas:name>    
               <bas:value>    
                  <bas:string_value>$msg</bas:string_value>    
               </bas:value>    
               <bas:value_type>STRING</bas:value_type>    
            </bas:NameValue_element>    
            <bas:NameValue_element>    
               <bas:name>severity</bas:name>    
               <bas:value>    
                  <bas:string_alue>$severity</bas:string_value>    
               </bas:value>   
               <bas:value_type>STRING</bas:value_type>    
            </bas:NameValue_element>              
            <even:subject></even:subject>    
         </imap:message>    
         <imap:timeout>60</imap:timeout>    
         <imap:messageClass>EVENT</imap:messageClass>    
         <imap:messageType>MSG_TYPE_NEW_EVENT</imap:messageType>    
      </imap:SendEvent>    
   </soapenv:Body>    
</soapenv:Envelope>    
"@    
[xml]$ret = Invoke-WebRequest $url -Method post -ContentType 'text/xml' -Body $soap -Headers $headers    

$mc_ueid = $ret.GetElementsByTagName("imap:response").'#text'    

$headers = @{ "SOAPAction" = "Disconnect"}    
$soap = [xml]@"    
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soapenvelope/" xmlns:imap="http://blueprint.bmc.com/ImapiElems">
       <soapenv:Header/>
       <soapenv:Body>
          <imap:Disconnect>
             <imap:connection>$connectionId</imap:connection>
             <imap:deleteBuffer>No</imap:deleteBuffer>    
      </imap:Disconnect>    
   </soapenv:Body>    
</soapenv:Envelope>    
"@    
$ret = Invoke-WebRequest $url -Method post -ContentType 'text/xml' -Body $soap -Headers $headers    

write-host $mc_ueid

================================================ =================================

【问题讨论】:

  • 这里是上述 PS 脚本communities.bmc.com/thread/92279 的来源,但我想修改和增强这个脚本以供我自己使用。所以我想了解要使用哪些功能。如何?在 perl 中“SOAP::lite 模块是最好的一种使用”是从研究中得到的。
  • 我不知道你是从什么研究中得到的,但比起可怕的 SOAP::Lite,强烈推荐 XML::Compile::SOAP,并且得到作者更好的支持。
  • @Grinnz 非常感谢。,但我想知道 -----[xml]$ret = Invoke-WebRequest $url -Method post -ContentType 'text/xml' 的等效功能-Body $soap -Headers $headers------这个在perl中,我会通过你提到的模块????

标签: xml powershell perl web-services soap


【解决方案1】:

正如@Grinnz 评论的那样:请不要使用 SOAP::Lite,它很难看。在 Perl 中通过 HTTP 运行 SOAP 操作的事实上的标准是XML::Compile::SOAP,它非常完整、维护良好且文档齐全。但是,由于 SOAP 协议固有的复杂性,要​​理解它可能有点复杂。以下说明应该可以帮助您入门。

在你必须加载模块之前:

use XML::Compile::SOAP11;
use XML::Compile::WSDL11;

那么第一步就是创建一个WSDL对象并加载WSDL文件:

my $wsdl = XML::Compile::WSDL11->new;
$wsdl->addWSDL($wsdl_file);

如果你的 WSDL 文件依赖于一些 XSD 文件,那么你必须先加载它们,在 WSDL 之前,调用:

$wsdl->importDefinitions($xsd_file);

请注意,出于安全原因,XML::Compile 永远不会尝试加载在线资源;您必须手动下载它们,然后从磁盘加载它们。

第二步是编译对象。这实际上将在对象中创建持久代码引用,您可以在之后重复调用以执行操作。您将目标服务的 url 作为参数传递给编译器。例如,以下调用编译所有可用的操作:

$wsdl->compileCalls( address => $url);

在编译时,您还可以传递自己的 HTTP 传输对象,而不是依赖 XML::Compile 默认值。当您想要对传输层进行细粒度控制(例如设置 HTTP 代理,...)时,这很有用。例如使用 LWP::UserAgent :

my $ua = LWP::UserAgent->new( show_progress => 1 );
$wsdl->compileCalls( address => $self->url, user_agent => $ua );

现在您已准备好调用 Web 服务。您传递操作的名称和数据结构,如下所示:

my ( $answer, $trace ) = $wsdl->call( $ope, $data );

如果出现任何问题,调用就会终止。成功时,它返回一个 Perl 数据结构,该结构表示已解析的响应。就是这样!

XML::Compile 提供了很多有用的自省和调试方法。例如,编译后,您可以使用以下命令打印所有可用操作的列表:

$wsdl->printIndex;

显示给定操作的输入数据结构的详细信息:

$wsdl->explain( $ope, PERL => "INPUT", recurse => 1 );

在一个操作执行之后,trace对象可以用来获取很多关于事情如何发生的内部细节,例如:

$trace->printRequest;
$trace->printResponse;
$trace->printTimings;

【讨论】:

  • 让我试着用perl写一下上面的代码,然后尝试执行。如果我仍然没有得到它,请寻求您的帮助..再次感谢您的帮助。!!
  • 嗨@GMB,我有wsdl url:hostname:9080/imws/services/ImpactManager?wsdl如果我在浏览器中输入这个,我可以看到xml格式的定义树结构。但是现在我该如何下载这个作为文件?我怎么知道是否存在对 xsd 文件的依赖?如何也下载它们?
  • metacpan.org/pod/XML::Compile::WSDL11我找到了你这里提到的功能
  • @kaushikkm :只需复制您在浏览器中看到的内容并将其粘贴到本地文件中即可。对于 XSD,您必须查看内容并搜索指向外部资源的 «xsd » 标签
  • 好的,我可以将它复制并粘贴到一个文件中。我应该用什么扩展名保存它?
猜你喜欢
  • 2014-12-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-01
  • 2013-11-08
  • 1970-01-01
  • 2013-08-20
  • 1970-01-01
相关资源
最近更新 更多