【问题标题】:Perl Dancer - JSON serializer and JSON arraysPerl Dancer - JSON 序列化器和 JSON 数组
【发布时间】:2014-09-30 12:20:44
【问题描述】:

我在使用用于 JSON 和 JSON 数组的内置 Perl Dancer 序列化程序时遇到问题。

我在 app.pl 文件中激活了序列化程序:

#!/usr/bin/env perl
use Dancer;
use main;

set serializer => 'JSON';

dance;

在模块本身中,我测试了这样的 JSON 解析:

post '/test/' => sub {
    my $params = request->params;

    debug('Test: ', $params);
};

现在我想确保按预期解析 JSON,因此我尝试使用 cURL 来了解序列化程序的工作方式:

curl -H "Content-Type: application/json" -X POST http://localhost:3000/test/ -d '{ "Name" : "foo", "email" : "bar" }'

结果如预期:

Test: {'Name' => 'foo','email' => 'bar'}

但是试图发送一个数组:

curl -H "Content-Type: application/json" -X POST http://localhost:3000/test/ -d '[{ "Name" : "foo", "email" : "bar" }]'

导致:

Test: {}

我希望序列化程序返回一个数组引用,但它似乎返回一个空哈希。我尝试以相反的方式使用序列化程序,但编码 JSON 似乎按预期工作。我做错了什么?

【问题讨论】:

  • 这是做什么的? curl -H "Content-Type: application/json" -X POST http://localhost:3000/test/ -d '{ "Name" : "foo", "email" : "bar" },{ "Name" : "baz", "email" : "baz@baz.newt" }'
  • 对不起,Dancer doc on params 表示它在标量上下文中处理哈希。思想也许可以迫使它散列。
  • 无论如何谢谢你——很可能我使用了错误的方法来访问我发送的 JSON。我试图创建一个类似的 JSON:curl -H "Content-Type: application/json" -X POST http://localhost:300/test/ -d '{ "testA" : { "Name" : "foo", "email" : "bar" }, "testB" : { "Name" : "baz", "email" : "baz@baz.newt" }}' 这会返回预期的:Test: {'testA' => {'Name' => 'foo','email' => 'bar'},'testB' => {'Name' => 'baz','email' => 'baz@baz.newt'}} 但将其放入数组 [ { "Name" : "foo", "email" : "bar" }, { "Name" : "baz", "email" : "baz@baz.newt" }] 仍然会返回 Test: {}

标签: arrays json perl serialization dancer


【解决方案1】:

我以为我有执行此操作的代码,但结果错了。

我无法让参数解析任何深度的东西。也许这是设计使然,但从文档中我并不清楚。

直接使用 from_json 函数可以解析 request->body ,其中包含 POST 的 JSON 字符串:

注意:我使用'd Data::Dumper 打印变量内容以使其更清晰一些。

post '/test/' => sub {
 #my @params =   params  ;
 #my @params =   request->body;
 my $body = request->body;

 my $j_O = from_json( $body );

 #deubg( 'Test1: ' . Dumper( request->body ) );
 #debug( 'Test2: ' . Dumper( request->params ) );
 #debug( 'Test3: ' . Dumper( { params }  ) );
 debug( 'Test4: ' . Dumper( $body ) );
 debug( 'Test5: ' . Dumper( $j_O ) );


};

输出:

[27993] debug @0.001528> [hit #2]Test4: $VAR1 = '[ { "Name" : "foo", "email" : "bar" }, { "Name" : "bar"} ]'; in /media/truecrypt1/Projects/Perl5+/Dancer/Test/lib/Test.pm l. 23
[27993] debug @0.001772> [hit #2]Test5: $VAR1 = [
          {
            'email' => 'bar',
            'Name' => 'foo'
          },
          {
            'Name' => 'bar'
          }
        ];

【讨论】:

  • 感谢您的回答。我用[ { "Name" : "foo", "email" : "bar" }, { "Name" : "baz", "email" : "baz@baz.newt" }] 尝试过,它什么也没返回。对于这个哈希 { "Name" : "foo", "email" : "bar" } 我收到 4 条调试消息:Test: email; Test: bar; Test: Name; Test: foo 如果您在查看代码后能更新您的答案,我会很高兴!
  • 希望您能在我得到我的代码之前得到一个更好更完整的答案。 :)
  • 非常感谢 - 现在可以使用了!似乎 JSON 序列化器毕竟不是我的问题。
  • 谢谢!!我现在可以从我的 Dancer2 后端的 Angular 应用程序中获取从 $http.post() 传递的 JSON 数据。
【解决方案2】:

我也遇到过同样的问题。 Dancer 序列化程序框架不能反序列化 HASH 数据类型以外的任何内容。我怀疑这是因为在 Dancer 内部,您可以执行诸如 params->{'foo'} 之类的操作来获取元素。 Dancer::Serializer 中的这段代码(~第 110 行)就是这个原因。

if (!ref $new_params or ref $new_params ne 'HASH') {
    return $request;
}

对我来说,有一些方法我需要将数组传递给请求。这导致我无法使用标准序列化程序框架,但我想在我的 config.yml 中保留相同的选项。

这是我的解决方案:

  my $json_object = from_json(request->body, config->{'engines'}->{'JSON'});

这将使用您在 config.yml 中为 JSON 引擎指定的配置选项返回一个 JSON 对象(Array 或 HashRef)。您可能希望也可能不希望将其包装在 eval 中。

【讨论】:

    猜你喜欢
    • 2018-12-18
    相关资源
    最近更新 更多