无法在Perl SOAP服务器代码中访问对象的实例变量

时间:2011-07-29 23:44:10

标签: perl soap

我正在使用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。)

...谢谢

2 个答案:

答案 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;