JSON解码失败

时间:2019-06-20 09:25:19

标签: json perl

以下是我观察到错误的代码段:“格式错误的JSON字符串,数组,对象,数字,字符串或原子都不位于字符偏移量0(在“((字符串末尾)”之前))“

观察到的错误在decode_json行。有人可以指出是什么错误吗?

my $serverurl = "http://mycompany.net/rest/api/2/";

my $username        = 'my.email@domain.com';
my $password        = "mypassword\@2019";
my $i ;
my $test;

my $headers = {Accept => 'application/json', Authorization => 'Basic ' .encode_base64($username . ':' . $password)};
my $client = REST::Client->new();

my $idartinstance;
my $idartinstance1;

 if (!$idartinstance)
    {
        print " Trying to Connect to URL using REST client interface \n\n";
        $idartinstance1 = $client->GET($serverurl."serverinfo",$headers);

        $idartinstance = decode_json($idartinstance1->responseContent());

    }

当我打印$idartinstance时,我得到了:

REST::Client=HASH(0x8682024)->responseContent()

这是否意味着它无法找到REST客户端?

[EDIT]我已经如下修改了脚本,并且在错误上没有区别。

my $serverurl = "https://mycompany.net/rest/api/3/";
my $username        = 'my.email@domain.com';
my $password        = 'pf9fCdkGXmi4pMHiwIh74A0D';

my $headers = {Accept => 'application/json', Authorization => 'Basic ' . encode_base64($username . ':' . $password)};

my $client = REST::Client->new();
if (!$idartinstance)
    {
        print " Trying to Connect to JIRA using REST client interface \n\n";

        $client->GET($serverurl."serverInfo", $headers);
        print $client->responseContent();
        $idartinstance = decode_json($client->responseContent());
    }

现在我已使用编码密码。错误相同:格式错误的JSON字符串,数组,对象,数字,字符串或原子都不位于字符偏移量0(“(字符串结尾)”之前)。尝试通过网络浏览器访问“ https://mycompany.net/rest/api/3/serverInfo”并能够获取详细信息。

2 个答案:

答案 0 :(得分:2)

收到回复后,您必须检查其是否符合要求。

if( $client->responseCode() eq '200' ){
    print "Success\n";
}

您可能还需要检查内容类型是否符合您的期望。如果应该是JSON,请检查它是否是

if( $client->responseHeader('Content-Type') =~ m|\Aapplication/json\b| ) {
    print "Got JSON\n";
}

一旦确定自己具有所需的内容,就将消息正文传递给JSON解码器。

my $data = decode_json($client->responseContent());

您还可能尝试在应该具有有效JSON但没有JSON的地方捕获错误。 eval块可以处理此问题(并查看eval的最佳使用方式的多种来源,以使其得到最佳利用):

my $data = eval { decode_json(...) };

我发现在两种情况下我倾向于得到错误的内容:

  • 错误的端点,404处理程序从该端点返回HTML
  • 强制性门户网站,该门户网站还返回HTML

答案 1 :(得分:0)

我认为您误读了the documentation for the module。从那里的提要,最类似于您的示例是第一个示例:

my $client = REST::Client->new();
$client->GET('http://example.com/dir/file.xml');
print $client->responseContent();

尤其要注意,此示例对GET()的返回值不执行任何操作。在您的示例中,您可以执行以下操作:

my $client = REST::Client->new();
my $resp = $client->GET('http://example.com/dir/file.xml');
print $resp->responseContent();

碰巧,尽管GET()中没有记录的返回值[更新:我在这里错了-请参阅第一个注释-但返回值实际上仅用于链接方法调用],它实际上返回已传递的对象,因此您的方法应该可行。但是,不遵循文档通常是一个坏主意。

那么实际上出了什么问题?好吧,我不确定。正如我所说,您的方法应该(偶然)起作用。但是,您收到的错误消息告诉我们,您传递给decode_json()的内容是REST :: Client对象,而不是包含JSON的字符串。我不认为您的代码应该这样工作。也许您显示给我们的代码实际上不是您正在运行的代码。

调试此问题的最佳方法是在您的问题的第一个注释中遵循Quentin的建议-在将要传递给decode_json()的值传递给函数之前,先打印该值。实际上,这是很好的常规编程建议-最初逐步编写代码,并且只有在知道各个步骤都可以正常工作时才组合步骤。

使用变量名,我认为您的代码应如下所示:

my $client = REST::Client->new();

# ...other code...

$client->GET($serverurl."serverinfo", $headers);

print $client->responseContent();

# And, only once you've established that
# $client->responseContent() returns what
# you expect, you can add this:

$idartinstance = decode_json($client->responseContent());

如果print()语句未向您显示JSON,则update your question添加要打印的内容,我们将做进一步的研究。