当前位置: 首页 > 知识库问答 >
问题:

SOAP::Lite Perl模块发送错误的SOAP信封命名空间

郑功
2023-03-14

我在编写一个SOAP/XML客户机与一家名为Domainbox的公司提供的API对话时遇到了问题。我正在使用SOAP::Lite模块/库用Perl编写客户机。我收到以下错误信息:

可能的SOAP版本不匹配:信封命名空间http://schemas.xmlsoap.org/soap/envelope/是意外的。期待http://www.w3.org/2003/05/soap-envelope.

这是因为库使用 SOAP 1.1 命名空间发送 SOAP 信封,而服务器需要 SOAP 1.2。

但是我不能想出一个解决方案,我已经尝试显式设置$soap-

服务器正在运行ASP.net,似乎不想接受SOAP版的消息。

默认情况下,查询soapversion()方法会返回版本1.1,当我将其更改为1.2时,它会返回1.2,但在内部,它显然忽略了这一点。

WSDL 似乎没有正确定义 xmlns:soap 或 xmlns:soap12,但 SOAP::Lite 也没有使用这些命名空间。我会提供一个链接,但我不允许在这里发布超过两个。

我也尝试使用SOAP::Lite的service()方法,但这没有任何区别。

这是我正在使用的代码:

#!/usr/bin/perl -w
use strict;
use SOAP::Lite;
use Data::Dumper;

### API Info
my $reseller = 'Removed';
my $username = 'Removed';
my $password  = 'Removed';

my $soap = SOAP::Lite->new(proxy => 'https://sandbox.domainbox.net/');
$soap->default_ns('https://sandbox.domainbox.net/');
$soap->soapversion('1.2');

my $header = SOAP::Header->new->attr({xmlns => 'https://sandbox.domainbox.net/'});

my $body = SOAP::Data->name('CheckDomainAvailability' => \SOAP::Data->value(
            SOAP::Data->name('AuthenticationParameters' => \SOAP::Data->value(
                SOAP::Data->name('Reseller' => $reseller),
                SOAP::Data->name('Username' => $username),
                SOAP::Data->name('Password' => $password),
            )
        )
    )
);

$soap->on_action( sub { "https://sandbox.domainbox.net/" });
my $som = $soap->call('',
$header,
$body
);

die $som->faultstring if ($som->fault);
print $som->result, "\n";

#print Dumper($som);

附加:

信封中的 xmlns:soap 属性设置为 http://schemas.xmlsoap.org/soap/envelope 无论类中的 soapversion 设置如何。我认为这是Perl模块中的一个错误,或者是WSDL的奇怪之处导致了它。下面是 WSDL:http://sandbox.domainbox.net/?WSDL

XML请求消息:

<?xml version="1.0" encoding="UTF-8"?><Envelope 
soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" 
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" 
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org
/2001/XMLSchema-instance"><Header><c-gensym3 
xmlns="https://sandbox.domainbox.net/" /></Header><Body><DomainboxAPI 
xmlns="https://sandbox.domainbox.net/"><CheckDomainAvailability>
<AuthenticationParameters><Reseller 
xsi:type="xsd:string">Removed</Reseller><Username 
xsi:type="xsd:string">Removed</Username><Password 
xsi:type="xsd:string">Removed</Password></AuthenticationParameters>
</CheckDomainAvailability></DomainboxAPI></Body></Envelope>

XML响应消息:

<?xml version="1.0" encoding="utf-8"?><soap:Envelope 
xmlns:soap="http://www.w3.org/2003/05/soap-envelope" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:xsd="html" target="_blank">http://www.w3.org/2001/XMLSchema"><soap:Header>
<soap12:Upgrade xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
<soap12:SupportedEnvelope qname="soap12:Envelope" 
xmlns:soap12="http://www.w3.org/2003/05/soap-envelope"/></soap12:Upgrade>
</soap:Header><soap:Body><soap:Fault><soap:Code>
<soap:Value>soap:VersionMismatch</soap:Value></soap:Code><soap:Reason>
<soap:Text xml:lang="en">Possible SOAP version mismatch: Envelope 
namespace  was unexpected. Expecting http://www.w3.org/2003/05/soap-
envelope.</soap:Text></soap:Reason><soap:Detail /></soap:Fault>
</soap:Body></soap:Envelope>

更新:

谢谢鲍罗廷,你说对了。SOAP::Lite模块似乎没有将soapversion参数传递给SOAP::Lite::Serializer对象。我现在使用下面的代码来初始化SOAP对象,它工作得很好。

my $soap = SOAP::Lite->new(proxy => 'https://sandbox.domainbox.net/');
$soap->default_ns('https://sandbox.domainbox.net/');
$soap->soapversion('1.2');
$soap->serializer->soapversion('1.2');

我应该指出,我还必须调整我的代码以适应Domainbox要求的XML格式,但是我现在得到了有效的响应。

我现在唯一的问题是如何处理SOAP::Lite::SOM作为消息结果返回的散列引用。我认为这需要一个单独的问题。

共有1个答案

韦锦程
2023-03-14

博罗丁对我的问题给出了答案。正确的代码是在SOAP::Lite对象和SOAP::Lite::Serializer对象上使用soapversion方法。以下是一个工作示例:

my $soap = SOAP::Lite->new(proxy => 'https://sandbox.domainbox.net/');
$soap->default_ns('https://sandbox.domainbox.net/');
$soap->soapversion('1.2');
$soap->serializer->soapversion('1.2');
 类似资料:
  • 问题内容: 以下是我应从Java Web应用程序调用的.NET Web服务的通用SOAP请求示例: 我可以使用以下代码段从Java控制台应用程序生成类似的内容: 结果是以下XML: 这将调用服务。接下来,我使用 soapUI 尝试调用此服务,并像这样从WSDL生成了soap消息(它 与 前面的信封和前缀中的名称空间声明 不同 ): 这也可以在soapUI中使用。但是最后,当我尝试使用以下代码序列重

  • 只有在soap信封已被移除的情况下,JAXB才能解组XML。然而,我试图解组的SOAP响应在SOAP信封上有其名称空间声明。如果删除soap信封,名称空间声明也将被删除。因此,标签的前缀将指无。这会导致JAXB抛出错误。如果在SOAP信封上声明了名称空间,如何使用JAXB对SOAP响应进行解组? 我需要解组的XML的类似示例如下: 如果我拿掉肥皂信封,会发生这样的事情: 如果我移除soap信封,名

  • 问题内容: 在花了几个令人沮丧的时间后,我正在寻求您的帮助。 我正在尝试从SOAP响应中获取特定节点的内容。 响应是 我试图了解 的节点和子节点。由于XML包含名称空间 不起作用。我已经阅读了许多文章,例如 http://www.sitepoint.com/blogs/2005/10/20/simplexml-and-namespaces/ http://blog.stuartherbert.co

  • XML信封命名空间的正确URI是什么。我见过很多,例如。”http://www.w3.org/2001/12/soap-envelope“,”http://www.w3.org/2001/06/soap-envelope“,”http://www.w3.org/2003/05/soap-envelope“,”http://schemas.xmlsoap.org/soap/envelope/“。请告

  • 问题内容: 如果已删除肥皂信封,JAXB只能解组XML。但是,我要解组的SOAP响应在soap信封上有其名称空间声明。如果我删除肥皂信封,则名称空间声明也将被删除。因此,标签的前缀将不涉及任何前缀。这将导致JAXB引发错误。如果在SOAP信封上声明了名称空间,如何使用JAXB解组SOAP响应? 我需要解组的XML的类似示例如下: 如果我取下肥皂信封,会发生以下情况: 如果删除了肥皂信封,则名称空间