我正在使用SOAP :: Transport :: HTTP:Daemon和SOAP :: Lite来处理示例SOAP客户端/服务器代码,我注意到我无法访问在对象的new()方法中声明的实例变量。我确定我做错了什么,但我不确定是什么(虽然我已经多年了,因为我是一个不太合适的Perl程序员)。
这是我的服务器:
#! /usr/bin/env perl
use lib '/a/valid/directory/modules';
use SOAP::Transport::HTTP;
my $port = 9810;
my $dispatchers = {
'urn:remote_call' => 'ExampleLibrary::MyExample'
};
my $daemon = SOAP::Transport::HTTP::Daemon
-> new (LocalAddr => 'localhost', LocalPort => $port)
-> dispatch_with($dispatchers)
-> on_action(sub {return})
;
print "Connect to SOAP server at ", $daemon->url, "\n";
$daemon->handle;
这是我的客户端(位于服务器使用lib行中指定的目录,modules / ExampleLibrary / MyExample.pm):
package ExampleLibrary::MyExample;
use vars qw(@ISA);
@ISA = qw(Exporter SOAP::Server::Parameters);
use SOAP::Lite;
sub new {
my($class, %args) = @_;
my $self = bless({}, $class);
$self->{somevar} = 'somedata';
return $self;
}
sub remote_call {
my $self = shift;
my $envelope = pop;
# Swap out return statements and the data is returned correctly
# return SOAP::Data->type('xml' => 'foo');
return SOAP::Data->type('xml' => "$self->{somevar}");
}
1;
我确定我正确地访问了客户端 - 我可以在remote_call的return语句(注释掉的代码)中放入静态文本并查看它 - 但是指定为$ self-> {的对象数据somevar}永远不可见,有或没有引号。 (我正在使用SoapUI来点击服务器。)
有谁看到我错过了什么? (哦,我在Cygwin上使用Perl v5.10.1。)
...谢谢
答案 0 :(得分:1)
文档说
dispatch_with({ URI => MODULE, # 'http://www.soaplite.com/' => 'My::Class', SOAPAction => MODULE, # 'http://www.soaplite.com/method' => 'Another::Class', URI => object, # 'http://www.soaplite.com/obj' => My::Class->new, })
你有
my $dispatchers = { 'urn:remote_call' => 'ExampleLibrary::MyExample' };
也许应该是
my $dispatchers = { 'urn:remote_call' => 'ExampleLibrary::MyExample->new' };
否则(我推测)你的方法可能被调用为静态方法而不是实例方法(没有实例化实例)。
P.S。文档中对象实例化字符串缺少单引号让我感到困惑,因为它表明单个实例用于处理所有请求(这对我来说似乎不对)但也许这确实是这个实验性功能所需要的,你应该省略单引号。
答案 1 :(得分:1)
我从@ RedGrittyBrick的建议稍微调整一下代码后得到了这个工作(或许这正是他所建议的,我只是不理解它)。还要感谢@ Axeman - 你多次回来尝试帮助 - 我非常感激。我在服务器中添加注释以指示修复内容的两行。
这是经过修改的服务器:
#! /usr/bin/env perl
use lib '/a/valid/directory/modules';
use ExampleLibrary::MyExample; # new!
use SOAP::Transport::HTTP;
my $port = 9810;
my $dispatchers = {
# new--no quotes around the hash value
'urn:remote_call' => ExampleLibrary::MyExample->new
};
my $daemon = SOAP::Transport::HTTP::Daemon
-> new (LocalAddr => 'localhost', LocalPort => $port)
-> dispatch_with($dispatchers)
-> on_action(sub {return})
;
print "Connect to SOAP server at ", $daemon->url, "\n";
$daemon->handle;
这是经过修订的客户。实际上,唯一的变化是放入localtime()调用,以便我可以验证在new()中设置的变量在服务器的生命周期内保持不变。
package ExampleLibrary::MyExample;
use vars qw(@ISA);
@ISA = qw(Exporter SOAP::Server::Parameters);
use SOAP::Lite;
sub new {
my($class, %args) = @_;
my $self = bless({}, $class);
$self->{'somevar'} = localtime();
return $self;
}
sub remote_call {
my $self = shift;
my $envelope = pop;
$now = localtime();
return SOAP::Data->type('xml' => "now = $now, started at $self->{somevar}");
}
1;