我正在使用SOAP::WSDL
和另一家公司的自定义WSDL文件。每当他们为我做出改变并重新创建我的模块时,就会出现问题。找到问题相当繁琐,因为我找不到合适的方法来访问发送到SOAP服务器的实际请求。
到目前为止,获取请求的唯一方法是使用tcpdump与wireshark一起提取请求和结果。这是有效的,但由于我在开发机器上没有root权限,所以每次我想要这样做时都需要管理员。我觉得必须有另一种方法来到HTTP::Request
内的SOAP::WSDL
对象。但是如果服务器返回错误,我甚至没有响应对象,而是一个与请求没有明显关系的SOAP::WSDL::SOAP::Typelib::Fault11
对象。
我也尝试过使用调试器,但是我找不到实际的请求部分。我还没有理解如何告诉debuger跳到复杂数量的包内的特定部分。
答案 0 :(得分:4)
我偶然发现了这个问题,我自己也遇到了同样的问题。我发现答案是使用raina77ow列出的两个选项。
$service->outputxml(1);
返回整个SOAP信封xml,但这需要与
结合使用$service->no_dispatch(1);
设置no_dispatch后,将打印SOAP请求,而不是请求的回复。希望这可以帮助其他人。
答案 1 :(得分:2)
您是否尝试使用SOAP::WSDL::Client跟踪方法 - 尤其是outputxml?它返回要发送到服务器的原始SOAP信封。
您还可以使用no_dispatch包的SOAP::WSDL配置方法:
设置后,call()返回普通请求XML而不是调度 SOAP调用SOAP服务。方便测试/调试。
答案 2 :(得分:0)
我找到了一种至少打印出生成的XML代码的方法。
首先,我按照raina77ow的建议看了SOAP::WSDL::Client。但这不是我所需要的。但后来我遇到了SOAP::WSDL::Factory::Serializer。在那里,它说:
Serializer对象也可以直接传递给SOAP :: WSDL :: Client 通过使用set_serializer方法。
有点烦躁,我想出了SOAP::WSDL::Serializer::XSD的包装类,它是SOAP::WSDL使用的默认序列化程序。看一下代码也有帮助。
这是我写的模块。它使用SOAP::WSDL::Serializer::XSD
作为基类,并重载new
和serialize
方法。虽然它只传递new
的参数,但它从serialize
获取返回的XML并打印它,这足以进行调试。我不确定是否有办法将它放在某个地方,我可以很容易地得到它。
package MySerializer;
use strict;
use warnings;
use base qw(SOAP::WSDL::Serializer::XSD);
sub new {
my $self = shift;
my $class = ref($self) || $self;
return $self if ref $self;
# Create the base object and return it
my $base_object = $class->SUPER::new(@_);
return bless ($base_object, $class);
}
sub serialize {
my ($self, $args_of_ref) = @_;
# This is basically a wrapper function that calls the real Serializer's
# serialize-method and grabs and prints the returned XML before it
# giving it back to the caller
my $xml = ref($self)->SUPER::serialize($args_of_ref);
print "\n\n$xml\n\n"; # here we go
return $xml;
}
1;
以下是我的称呼方式:
my $serializer = MySerializer->new();
$self->{'_interface'} = Lib::Interfaces::MyInterface->new();
$self->{'_interface'}->set_serializer($serializer); # comment out to deactivate
很容易停用。只在set_serializer
行中发表评论。
当然,在命令行中打印一块XML并不是很漂亮,但它可以完成工作。我之前只需要编码/测试一次,所以我猜这很好。