Perl:从SOAP :: WSDL对象获取完整请求

时间:2012-04-30 08:52:31

标签: perl soap wsdl http-request

我正在使用SOAP::WSDL和另一家公司的自定义WSDL文件。每当他们为我做出改变并重新创建我的模块时,就会出现问题。找到问题相当繁琐,因为我找不到合适的方法来访问发送到SOAP服务器的实际请求。

到目前为止,获取请求的唯一方法是使用tcpdump与wireshark一起提取请求和结果。这是有效的,但由于我在开发机器上没有root权限,所以每次我想要这样做时都需要管理员。我觉得必须有另一种方法来到HTTP::Request内的SOAP::WSDL对象。但是如果服务器返回错误,我甚至没有响应对象,而是一个与请求没有明显关系的SOAP::WSDL::SOAP::Typelib::Fault11对象。

我也尝试过使用调试器,但是我找不到实际的请求部分。我还没有理解如何告诉debuger跳到复杂数量的包内的特定部分。

3 个答案:

答案 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作为基类,并重载newserialize方法。虽然它只传递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并不是很漂亮,但它可以完成工作。我之前只需要编码/测试一次,所以我猜这很好。