トップ 差分 一覧 ソース 検索 ヘルプ PDF RSS ログイン

JSON

mojolicious JSON POST

mojoliciousでJSONをPOSTで送信と受信

デモ画面を作ってみた。

[toolmmt/templates/json/json.html.ep]

% layout 'default';
% title 'mojplicious JSON DEMO';
<h2>mojolicious JSON Demo</h2>
<hr><h4>JSON</h4>
<ul>
  <li><a href="http://www21051ue.sakura.ne.jp:3003/api/json/json_test01">json_test001</a></li>
</ul>
<h4>JSON POST</h4>
<script type="text/javascript">
    $(function(){
        $("#response").html("Response Values");
        $("#button").click( function(){
            var url = $("#url_post").val();
                var JSONdata = {
                    value1: $("#value1").val(),
                    value2: $("#value2").val()      
                };
            // alert(JSON.stringify(JSONdata));
            $.ajax({
                type : 'post',
                url : url,
                data : JSON.stringify(JSONdata),
                contentType: 'application/JSON',
                dataType : 'JSON',
                scriptCharset: 'utf-8',
                success : function(data) {
                    // Success
                    // alert("success");
                    // alert(JSON.stringify(data));
                    $("#response").html(JSON.stringify(data,null,"  ")); //JSONを整形
                },
                error : function(data) {
                    // Error
                    alert("error");
                    alert(JSON.stringify(data));
                    $("#response").html(JSON.stringify(data));
                }
            });
        })
    })
</script>

    <h1>HTMLファイルからPOSTでJSONデータを送信する</h1>
    <p>URL: <input type="text" id="url_post" name="url" size="100" value="<%== url_for %>"></p>
    <p>value1: <input type="text" id="value1" size="30" value="値1"></p>
    <p>value2: <input type="text" id="value2" size="30" value="値2"></p>
    <p><button id="button" type="button">submit</button></p>
    <textarea id="response" cols=120 rows=10 disabled></textarea>

[toolmmt/lib/Tool/mmt/Controller/Json.pm]

package Tool::mmt::Controller::Json;
use Mojo::Base 'Mojolicious::Controller';

sub json_post{
    my $s = shift;
    use Mojo::UserAgent;
    my $ua = Mojo::UserAgent->new;
    my $data = $ua->post('http://localhost:3001/api/example/json' =>  {Accept=> '*/*'} => json => {a => 'b'});
    $s->render(json => $data->res->json);
}
sub json_test01{
    my $s = shift;
    $s->render(json => {head => 'Json Test Data',array=>[1,2,3,4],lang=>['perl','ruby','php'],
        日本語=>['漢字','ひらがな','カタカナ']});
}

sub json{
    my $s = shift;
    $s->render(json => $s->req->json);
}

1;

perl6も使って見よう

JSONシリアライズとデシリアライズ

$ perl6 -MJSON::Tiny -e 'say from-json(q{ { "a": 42 } }).perl; say to-json { a => [1, 2, <b>] };'
{:a(42)}
{ "a" : [ 1, 2, "b" ] }
$

JSON:いつの間にか簡単になっていた

mojoliciousとjQueryを使えば何も考えずにJSONデータのやりとりが出来てします。

・サーバーからJSONを送信

sub flick{
  my $self = shift;
  my $json = $self->app->album->flick($self);
  $self->render(json => $json);
}

・サーバーよりJSONを受信

                           $.ajax({
                               url: '/flick',
                               type: 'GET',
                               dataType: 'json',
                               data: {
                                   _action: 'flick',
                                   _name: document.img.src,
                                   _count: '1',
                               },
                               success: function( data,textStatus,jqXHR){
                                   document.img.src=data.name;
                                   $("#bigimg").attr("href",data.name);
                                   $("<img>").attr("src",data.preload);
                               }
                           })

photo_albumより抜粋)

・実際にJSONを受信してみる

$ wget -S http://www21051ue.sakura.ne.jp:3000/flick
--2015-03-03 22:51:47--  http://www21051ue.sakura.ne.jp:3000/flick
www21051ue.sakura.ne.jp (www21051ue.sakura.ne.jp) をDNSに問いあわせています...  49.212.186.65
www21051ue.sakura.ne.jp (www21051ue.sakura.ne.jp)|49.212.186.65|:3000 に接続しています... 接続しました。
HTTP による接続要求を送信しました、応答を待っています... 
 HTTP/1.1 200 OK
 Connection: keep-alive
 Content-Type: application/json
 Date: Tue, 03 Mar 2015 13:51:47 GMT
 Content-Length: 68
 Server: Mojolicious (Perl)
長さ: 68 [application/json]
`flick.1' に保存中

100%[======================================>] 68          --.-K/s   時間 0s    

2015-03-03 22:51:47 (4.18 MB/s) - `flick.1' へ保存完了 [68/68]

$ cat flick.1
{"preload":"img\/1379065566324.jpg","name":"img\/1379065566324.jpg"}
$

JSONメモ

JSON日の金曜日 に行ってきた

ギークハウス新潟JSONの勉強会に参加してきた。いつもながら楽しかったヨ!!! ギー潟のリビングで開催された勉強会、開始の挨拶の後に5人の方が発表し、その後飛び入りで3人が発表しました。その3人目に私も軽いLT(このページ)をやらせてもらいました。私は、PCを持っていないので@NkznさんのPCをお借りしました。(ありがとう!)ギー潟リビングではMAC比率高かった。ほぼMACでMAC9台?、Win1台、手ぶら1人(私)って感じでした。発表内容は早くもsasa+1さんが発表内容をまとめてくれています。---

私の発表内容

2012年7月13日の金曜日にジェーソン(JSON)の勉強会が新潟で行われるのでJSONについて調べてみた。AJAXでサーバーからデータを受けとるのにXMLよりJSONの方がそのままevalで処理出きるので便利(危険)だ。perlでは作成も簡単で、人間にも見やすいので人間にも機械にもやさしいデータフォーマットだと思う。調べるだけでは何なので実際にWebでサンプルページを作ってみた。

JSONとは

JSON の紹介より(http://www.json.org/)

JSON (JavaScript Object Notation)は、軽量のデータ交換フォーマットです。人間にとって読み書きが容易で、マシンにとっても簡単にパースや生成を行なえる形式です。 JavaScriptプログラミング言語 (ECMA-262標準第3版 1999年12月)の一部をベースに作られています。 JSONは完全に言語から独立したテキスト形式ですが、C、C++、C#、Java、JavaScript、Perl、Python、その他多くのCファミリーの言語を使用するプログラマにとっては、馴染み深い規約が使われています。これらの性質が、 JSONを理想的なデータ交換言語にしています。

JSONは2つの構造を基にしています。

  • 名前/値のペアの集まり。様々な言語で、これはオブジェクト、レコード、構造体、ディクショナリ、ハッシュテーブル、キーのあるリスト、連想配列として実現されています。
  • 値の順序付きリスト。ほとんどの言語で、これは配列として実現されています。

データフォーマット

  • 連想配列
{"name":"John Smith","arg":50}
  • 配列
["perl","ruby","JavaScript","JSON"]
  • 連想配列と配列の組み合わせ
{"languages":["Perl","Ruby","Python"],
  "DATA":["JSON","XML","CSV"]
}

サンプルを作ってみる

サーバーのデータを参照しJSON形式でレコードを返しJavaScriptでTABLE形式にフォーマットし表示するだけのサンプルを作ってみた。

・フロー
+-----------------+ request +----------------+      +-----------+
|                 |-------->|                |      |           |
|  json01.cgi     |         |    get.cgi     |<---->|  MySQL    |
|                 |<--------|                |      |           |
+-----------------+  JSON   +----------------+      +-----------+
  • json01.cgi
#!/usr/local/bin/perl

use mmt;
my $mmt = mmt->new();
print make_html();
undef $mmt;

sub make_html{
	$sql=$mmt->{dbh}->urlencode("select * from 機能一覧 order by rand() limit 10");
	my $res = <<END_HTML;
@{[$mmt->{in}->header(-type=>"text/html; charset=euc-jp")]}
<head>
<script type="text/javascript" src="js/prototype.js"></script> 
<script type="text/javascript"> 
function execute() { 
    var a = new Ajax.Request( 
        "get.cgi", 
        { 
            "method": "get", 
            "parameters": "act=JSON&sql=$sql", 
            onComplete: function(request) { 
                \$('container').innerHTML = request.responseText; 
                var json = eval("("+request.responseText+")");
                var text = "<table border=1>"; 
                for(var i=0;i< json.item.length;i++){
             text += "<tr>";
                    for (var  keyString in json.item[i]) {
                        text += "<td>" + json.item[i][keyString] + "</td>";
                    }
                    text += "</tr>";
                }
                text +=  "</table>"; 
                \$('jsondata').innerHTML = text; 
            }, 
            onFailure: function(request) { 
                alert('読み込みに失敗しました'); 
            } 
        } 
    ); 
} 
</script>
</head> 
<body> 
<H1>JSON</H1>
<button onclick="execute()">サンプル実行</button> 
<hr><div id="container">JSON DATA</div>
<hr><div id="jsondata">content</div>
</body> 
</html> 
END_HTML

return $res;
}
  • get.cgi
#!/usr/local/bin/perl

=pod

=head1 NAME

get.cgi - データ照会

=head1 概要


=cut

use strict;
use webdb;
use CGI qw/:standard :html3/;

use vars qw($in $dbh $sql);
$in = new CGI;
$dbh = new webdb;
$sql = $in->param('sql') || "select 取引先名 from 取引先マスタ where 取引先コード =  ?";
print header(-type=>"text/html; charset=euc-jp");
exit if($sql !~ /^\s*(select|show)/i);
if($in->param('act') eq 'JSON'){
	JSON();
}else{
	my $sth = $dbh->{'dbh'}->prepare($sql);
	$sth->execute($in->param('code'));
	while(my $ref = $sth->fetchrow_arrayref()){
		print $ref->[0];
	}
}
sub JSON{
	my $sth = $dbh->{dbh}->prepare($sql);
	$sth->execute($in->param('code'));
	print '{"item":[' . "\n";
	my @a = ();
	my @b = ();
	while(my $ref = $sth->fetchrow_hashref()){
		@b = ();
		for(@{$sth->{NAME}}){
			$ref->{$_} =~ s/\x00//g;
			push @b,qq{"$_":"$ref->{$_}"};
		}
		push @a,"{\n" . join(",\n",@b) . "}\n";
	}
	print join(',',@a);
	print "]\n}\n";
}

メモ

use mmt;
my $mmt = mmt->new();
$sql=$mmt->{dbh}->urlencode("select 分類No,機能名 from 機能一覧 limit 10");
print qq{<a href=get.cgi?act=JSON&sql=$sql >JSON</a>}
{"item":
 [
   { "分類No":"1", "機能名":"ホストデータ振り分け処理"} ,
   { "分類No":"1", "機能名":"ホストデータの取得(現物集中システムサーバ)"} ,
   { "分類No":"1", "機能名":"ホストデータのジェネレーション処理"} ,
   { "分類No":"1", "機能名":"ホストデータ受信更新処理"} ,
   { "分類No":"1", "機能名":"不動産担保データ受信更新処理"} ,
   { "分類No":"2", "機能名":"自店保管管理用データ抽出処理(日次)"} ,
   { "分類No":"2", "機能名":"不備返却管理用データ抽出処理(月次)"} ,
   { "分類No":"2", "機能名":"遅延管理用データ抽出処理(日次)"} ,
   { "分類No":"2", "機能名":"事務量集計データ抽出処理(日次)"} ,
   { "分類No":"2", "機能名":"事務量集計データ抽出処理(月次)"} 
 ] 
}