How can I get access to JSON in a mojo response?
$txn = $ua->post( $url, $headers, json => {json} )
What's the way to get the JSON response from the txn?
I have several examples in my book Mojolicious Web Clients, but here's the deal.
When you make a request, you get back a transaction object:
my $ua = Mojo::UserAgent->new;
my $tx = $ua->post( ... );
The transaction object has both the request and response (a major feature that distinguishes Mojo from LWP and even other user agent libraries in other languages). To get the response, you can use the res or result methods. The result dies for you if it couldn't make the request because a connection error occurred (ENONETWORK):
my $res = $tx->result;
Once you have the response, there are various things you can do (and these are in the SYNOPIS section of the Mojo::UserAgent. If you want to save the result to a file, that's easy:
$res->save_to( 'some.json' );
You can turn the content into a DOM and extract parts of HTML or XML:
my #links = $res->dom->find( 'a' )->map( attr => 'href' )->each;
For a JSON response, you can extract the contents into a Perl data structure:
my $data_structure = $res->json;
However, if you wanted the raw JSON (the raw, undecoded content body), that's the message body of the request. Think of that like the literal, unfiltered text:
use Mojo::JSON qw(decode_json);
my $raw = $res->body;
my $data_strcuture = decode_json( $raw );
Since this is the response object, Mojo::Message and Mojo::Message::Response show you what you can do.
Here's a complete test program:
#!perl
use v5.12;
use warnings;
use utf8;
use Mojo::JSON qw(decode_json);
use Mojo::UserAgent;
use Mojo::Util qw(dumper);
my $ua = Mojo::UserAgent->new;
my $tx = $ua->get(
'http://httpbin.org/get',
form => {
name => 'My résumé'
},
);
die "Unsuccessful request"
unless eval { $tx->result->is_success };
my $data_structure = $tx->res->json;
say dumper( $data_structure );
my $raw = $tx->res->body;
say $raw;
my $decoded = decode_json( $raw );
say dumper( $decoded );
I was able to get access to this data like this,
my $api_order = $tx_cart->result->json->{data};
It's in result not in body.
Related
I paid someone to make a plugin for my website 5 years ago and now I'm trying to get it to work again. I have no knowledge of how JSON works so this is my first experimenting with it. Basically my plugin would use the Iframely API to get a summary of an article and save the data to a custom field from a URL in the editor.
The code I have in question in my function.php is this:
function post_extra_save( $post_id, $post){
global $pagenow;
if ($pagenow == 'post.php') {
if ( has_post_format('link', $post_id)) {
$url = get_post_field('post_content', $post_id);
$request_url = 'https://iframe.ly/api/iframely?url='. urlencode($url) .'&api_key='.get_field_object('api_key', 'option')['value'];
$response = wp_remote_get( esc_url_raw( $request_url ) );
$api_response = json_decode( wp_remote_retrieve_body( $response ), true );
update_field('field_61942d74195e7', $api_response);
}
}
}
add_action( 'save_post', 'post_extra_save', 10, 2 );
What it does is send a URL plus the API key to Iframely API, returns the JSON and save the raw output to a custom field.
When I save the post, I get this error message:
Warning: htmlspecialchars() expects parameter 1 to be string, array given in /wp-includes/formatting.php on line 4529
Any idea what this means?
Found my problem. What I got it to work was it gets the URL from the post content, encode it from the raw JSON and decode it.
$request = wp_remote_get( 'https://iframe.ly/api/iframely?url='. urlencode($url) .'&api_key='.get_field_object('api_key', 'option')['value'] );
$data_raw = json_encode( wp_remote_retrieve_body( $request ));
$data = json_decode($data_raw);
So, I'm trying to store a decoded JSON object into a tied apache session. This is my code:
$url="https://apilink";
$content = get($url);
die "Can't Get $url" if (! defined $content);
$jsonOb = decode_json($content);
%aprecords = %$jsonOb;
#Push the jsonOb in the session
$session{apirecords} = \%aprecords ;
$session{apirecords} does not store the %aprecords reference. Although, when I substitute the statement to $session{apirecords} = \%jsonOb ; , it stores apirecords in the sessions table but the reference to %jsonOb has no values in it.
PS:
I have tried the following and none of them seem to work:
1) $session{apirecords} = \%$jsonOb ;
2) $session{apirecords} = { %aprecords } ;
JSON object is perfectly well structured.
Code for tying a session:
tie %session, "Apache::Session::MySQL", $sessionID,
{
Handle => $dbObject,
LockHandle => $dbObject,
TableName => 'sessions',
};
#If a session ID doesn't exist, create a new session and get new session ID
if (!defined ($sessionID)){
$sessionID = $session{_session_id};
$session{count}=0;
}
A helping hand would be much much appreciated!
JSON Sample: https://jsonblob.com/feed3bba-f1cd-11e8-9450-2904e8ecf943
As pointed out by GMB. The blob size(64 KB) wasn't big enough for the JSON object.
The solution is to change blob datatype to mediumblob .
for web services , how to retrieve the data json format using Laravel, can anybody help
https://test.com/admin/users/apiLogin?Login={"email":test#test.com,"pwd":testing}
in Controller
public function apiLogin(Request $request)
{
//$data = $request->json()->all();
$data=json_decode($request['Login']);
echo $data['email'];
echo "<pre>";
print_r($data);
echo "</pre>";
echo "testsetet";
exit;
}
To get the URL parameter use this:
$login = $request->input('login'); // or $request['Login']
The goal is to turn login (which is a string) into appropriate JSON format so that you can use json_decode.
I'll break it down in steps:
Remove all \n characters:
$login = str_replace('\n', '', $login);
Remove last comma
$login = rtrim($login, ',');
Add brackets
$login = "[" . trim($login) . "]";
Turn it into a PHP array:
$json = json_decode($login, true);
The issue here is that your url parameter 'Login' isn't properly formatted json. I would revisit your front-end code persisting this data and ensure it is formatting properly. True json should look like:
{"email":"test#test.com","pwd":"testing"}
As a BIG aside, never persist passwords in the URL. It is dangerously foolish. Use a POST request to do this. On the plus side, the back-end code will be virtually the same with your json_decode() logic.
I want to get some data from the URL above, I would like to get all of the torrent names under the search query.
http://kickass.to/usearch/grand%20theft%20auto%20v%20category:ps3/
Currently I got this code, but it just gets the html source from page, it would be great if someone could help me with parsing all the torrent names from the source.
function get_web_page( $url )
{
$options = array(
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HEADER => false,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_ENCODING => "",
CURLOPT_USERAGENT => "spider",
CURLOPT_AUTOREFERER => true,
CURLOPT_CONNECTTIMEOUT => 120,
CURLOPT_TIMEOUT => 120,
CURLOPT_MAXREDIRS => 10,
);
$ch = curl_init( $url );
curl_setopt_array( $ch, $options );
$content = curl_exec( $ch );
$err = curl_errno( $ch );
$errmsg = curl_error( $ch );
$header = curl_getinfo( $ch );
curl_close( $ch );
$header['errno'] = $err;
$header['errmsg'] = $errmsg;
$header['content'] = $content;
return $header;
}
$data = get_web_page('http://kickass.to/usearch/grand%20theft%20auto%20v%20category:ps3/');
print_r(htmlspecialchars($data['content']));
Is the use of PHP a requirement?
If not, the following groovy script solves your problem:
#Grab('org.codehaus.groovy.modules.http-builder:http-builder:0.6')
import groovyx.net.http.*
import groovy.xml.*
def http = new HTTPBuilder('http://kickass.to/usearch/grand%20theft%20auto%20v%20category:ps3/')
def html = http.get(path: '')
html.'**'.findAll { it.#class == 'torrentname' }.each { torrentNameDiv ->
def titleLink = torrentNameDiv.'*'.findAll { it.#class.text().contains('normalgrey') }?.getAt(0)
def title = titleLink.'*'.findAll { it.name() == 'STRONG' && it.#class == 'red' }.join(' ')
def info = titleLink[0].children().findAll { it instanceof String }.join(' ')
println "title=$title"
println "info=$info"
}
Behind the scenes there are groovy classes like HTTPBuilder, XmlSlurper and GPathResult. The navigation over HTML structure is done via GPathResult.
Documentation here:
http://groovy.codehaus.org/api/groovy/util/slurpersupport/GPathResult.html
http://groovy.codehaus.org/modules/http-builder/home.html
Example here:
http://binarybuffer.com/2012/05/parsing-html-pages-like-a-boss-with-groovy
Unless the html document is xhtml, it is probably not well-formed XML and you'll need an HTML parser rather than an XML parser... or you'll need to preprocess it into xhtml using something like the W3C's "tidy" tool, and then parse it as XML.
Once you get it into a standard W3C DOM, check whether that DOM implementation provides an implementation of XPath. If not, off-the-shelf implementations of XPath that run against user-provided DOMs are also available -- Apache Xalan is one obvious example. Xalan also implements XSLT, so you could combine gathering the data and arranging it into your desired format into a single stylesheet and avoid having to hand-code some of that.
I'm finding list of Areas for my CakePHP 2.x website and it supports, JSON output as below with find all method:
$this->Area->find('all', array('fields' => array('id', 'name', 'order'), 'conditions' => array('Area.status' => 1)));
Below is my JSON output:
[{"Area":{"id":"2","name":"Area 1","order":"1"}},{"Area":{"id":"3","name":"Area 2","order":"1"}}]
Now Is that possible for me to remove Area tag which is repeating everytime?
Any patch for same? Do let me know if any suggestions / ideas.
on your view for output json write this:
echo json_encode(Set::extract('/Area/.', $area));
For me works fine.
CakePHP Provides some in-built library functions for data extraction from result set and output same as JSON format.
// initialize your function to render false and response type json
$this->autoRender = false; // no view to render
$this->response->type('json');
// Remove Area from array and encode
$area = Set::extract('/Area/.', $area);
$json = json_encode( $area);
$this->response->body($json);
Hope it helps !