error handling for JSON data perl CGI Script - json

I am new to perl and I writing a simple cgi script in perl read Json data.. that looks like this
use CGI;
use JSON;
use strict;
my $cgi = CGI->new;
my $error=0;
$cgi->param();
my $data = $cgi->param('POSTDATA') || '{
"field1":"value1",
"field2":"value2"
}'; # Used a sample JSON with
my $json = JSON->new->utf8;
my $input = $json->decode ($data) || $error++;
my #errors=();
my %slots;
$slots{'coloumn1'} = $input->{'field1'} || $error++;
$slots{'coloumn2'} = $input->{'field2'} || $error++; # if there is no field2 in JSON it will increment value
if ( $error > 0) {
print $cgi->header('text/html','400 Bad Data');
print "error with $data ";
exit;
}
How can i do more sophisticated error handling for JSON to check if its a valid json string.....and raise exception if a field is missing in JSON string using eval or other methods??

Related

Perl script to parse JSON data

I am trying to create a script to parse JSON content but it is not working:
#!/usr/local/bin/perl-w
use DBI;
use Parallel::ForkManager;
use LWP::Simple;
use XML::Simple;
use JSON qw( decode_json );
use Data::Dumper;
use DateTime;
use WWW::Mechanize;
use strict;
use warnings;
use JSON;
my $ua = LWP::UserAgent->new();
my $req = new HTTP::Request GET => 'https://google.com/pub/';
my $res = $ua->request($req);
my $contents = $res->content;
##json response:
#{"success":true,"data":"{\"campaign\":\"21490|\",\"format\":\"md5 \",\"delta_timestamp\":\"1528992718\",\"result\":\"success\",\"download_link\":\"https:\\\/\\\/gmail.net\\\/accesskey\\\/getfile\\\/m-spqn-e61-2aef2575a0b5250354f2b0fda033e703?token=HUSYjdC5jyJskXUHiKn13l1A1BaAjH2R&dcma=e8fae90c472ae146\"}","message":null}
print $contents;
#Check the outcome of the Response
if ( $res->is_success ) {
print $res->content;
}
# Decode the main json object
my $jsn = decode_json($res);
# Since 'data' is another serialized object, you need to decode that as well:
my $data = decode_json($jsn);
# Now you can access the contents of 'data'
#want to extract download_link object
print $data->{'download_url'};
I am looking at the content of download_link.
use JSON qw(decode_json);
# from $res->content
my $content = '{"success":true,"data":"{\"campaign\":\"21490|\",\"format\":\"md5 \",\"delta_timestamp\":\"1528992718\",\"result\":\"success\",\"download_link\":\"https:\\\/\\\/gmail.net\\\/accesskey\\\/getfile\\\/m-spqn-e61-2aef2575a0b5250354f2b0fda033e703?token=HUSYjdC5jyJskXUHiKn13l1A1BaAjH2R&dcma=e8fae90c472ae146\"}","message":null}';
print decode_json(decode_json($content)->{data})->{download_link};

Perl JSON issue when string starts with [ and not {

Hope some Perl gurus out there can help me out here. Basically my issue is when a JSON string starts with a "[" instead of a "{", Perl doesn't treat the variable as a hash after I use decode_json.
Here's a sample code.
#!/usr/bin/perl
use JSON;
use Data::Dumper;
$string1 = '{"Peti Bar":{"Literature":88,"Mathematics":82,"Art":99},"Foo Bar":{"Literature":67,"Mathematics":97}}';
$string = '[{"ActionID":5,"ActionName":"TEST- 051017"},{"ActionID":10,"ActionName":"Something here"},{"ActionID":13,"ActionName":"Some action"},{"ActionID":141,"ActionName":"Email Reminder"}]';
print "First string that starts with \"{\" below:\n$string1\n\n";
my $w = decode_json $string1;
my $count = keys %$w;
print "printing \$count's value -> $count\n\n";
print "Second string starts with \"[\" below:\n$string\n\n";
my $x = decode_json $string;
my $count2 = keys %$x;
print "printing \$count2's value -> $count2\n\n";
Below is the script output.
Both $w and $x works though. It's just I have to use keys $x instead of keys %$x on the other json string.
Now the issue with using that is I get a keys on reference is experimental at tests/jsontest.pl error. It won't stop the script but I'm worried about future compatibility issues.
What's the best way to approach this?
Use the ref function to determine what type the reference is. See perldoc -f ref.
my $w = decode_json $string1;
my $count = 1;
if( my $ref = ref( $w ) ){
if( $ref eq 'HASH' ){
$count = keys %$w;
}elsif( $ref eq 'ARRAY' ){
$count = scalar #$w;
}else{
die "invalid reference '$ref'\n";
}
}

Perl REST call contains special characters

Hi I am calling REST call from Perl to SoLr. Below is the code which contains special characters in search criteria. When i check in the SoLr, the call doesn't receive the complete json string.
#!perl -w
use REST::Client;
use JSON;
use MIME::Base64;
use Redis;
my %Hash;
my %Data; my %Param; my #DataArray;
$Hash{archiveFlag} = '0';
$Param{Parameter} = "some.545";
$Param{SortBy} = "Age";
$Param{OrderBy} = "Up";
$Data{searchType} = "Fulltext";
$Data{parameters} = \%Param;
$DataArray[0] = \%Data;
$Hash{searchConditionWrapper} = \#DataArray;
my $Data = encode_json \%Hash;
print $Data;
$url="http://localhost:8181/DashboardDAVE/cont/solr";
my $headers = {'Accept' => 'application/json', 'Content-Type' => 'application/json'};
my $client = REST::Client->new();
$client->setHost($url);
$client->GET($Data, $headers);
print $client->responseContent();
Below is the error.
Exception while parsing json 1:null
Any help on this much appreciated.

How do I use encode_json with string in Perl?

Here is my code that I try to open the file to get data and change it to UTF-8, then read each line and store it in variable my $abstract_text and send it back in JSON structure.
my $fh;
if (!open($fh, '<:encoding(UTF-8)',$path))
{
returnApplicationError("Cannot read abstract file: $path ($!)\nERRORCODE|111|\n");
}
printJsonHeader;
my #lines = <$fh>;
my $abstract_text = '';
foreach my $line (#lines)
{
$abstract_text .= $line;
}
my $json = encode_json($abstract_text);
close $fh;
print $json;
By using that code, I get this error;
hash- or arrayref expected (not a simple scalar, use allow_nonref to allow this)
error message also point out that the problem is in this line;
my $json = encode_json($abstract_text);
I want to send the data back as a string (which is in UTF-8). Please help.
I assume you're using either JSON or JSON::XS.
Both allow for non-reference data, but not via the procedural encode_json routine.
You'll need to use the object-oriented approach:
use strict; # obligatory
use warnings; # obligatory
use JSON::XS;
my $encoder = JSON::XS->new();
$encoder->allow_nonref();
print $encoder->encode('Hello, world.');
# => "Hello, world."

How to check whether hash key contain JSON in perl?

I am sending a request to the endpoint url ,from there i am getting the response in case of success in form of JSON,but if it fails it return certain text .
Sending request:
$data->{response} = $self->{_http}->send($myData);
So before doing this:
$resp = from_json($data->{response});
i want to check whether the reponse is in json format or not .How we can handle this in Perl kindly help in this
You can catch exception thrown by from_json(),
my $resp;
my $ok = eval { $resp = from_json("{}"); 1 };
$ok or die "Not valid json";
or simpler,
my $resp = eval { from_json("rrr") };
$resp // die "Not valid json";
Use JSON or JSON::XS to decode the JSON into a Perl structure.
Simple example:
use strict;
use warnings;
use JSON::XS;
my $json = '[{"Year":"2012","Quarter":"Q3","DataType":"Other 3","Environment":"STEVE","Amount":125},{"Year":"2012","Quarter":"Q4","DataType":"Other 2","Environment":"MIKE","Amount":500}]';
my $arrayref = decode_json $json;
foreach my $item( #$arrayref ) {
# fields are in $item->{Year}, $item->{Quarter}, etc.
}
You could use a try/catch block using Try::Tiny
use Try::Tiny;
try {
$resp = from_json($data->{response});
} catch {
# Do something if it does not parse
warn 'Could not parse json'
};