CGIへスコア情報を送信する
(注)サーバは解約したのでスコア登録はできません。ご自身のサーバに置き換えてください。
サーバ上にあるCGIに接続し、スコア情報を送信するサンプルプログラムを書いてみます。ここではCGIをPerlという言語で書いています。 ServletやJSPを使うことでJavaでもCGIを作れます。しかし、レンタルサーバーで対応していることが少ないため今回はよく使われるPerl を選択しました。
ここでは、必要最小限の構成にするためコンソールアプリケーションを作りました。実行するにはファイルをダウンロードしてrun.batをダブルクリックしてください。
スコアを送信
手順をまとめると
- CGI に接続する
- CGIへの書き込みストリームを開く
- 書き込みストリームを通してCGIへデータを送信する
- CGIからの読み込みストリームを開く
- 読み込みストリームを通してCGIの出力を受信する
単純なので全コードを掲載します。
public class SendScore { public static void main(String[] args) { // もりの得点が1500だったというデータ String data = "name=もり&score=1500"; try { // CGIを表すURLオブジェクト URL cgiURL = new URL("http://javagame.main.jp/cgi-bin/score/send_score.cgi"); // 接続 URLConnection uc = cgiURL.openConnection(); uc.setDoOutput(true); uc.setUseCaches(false); // CGIへの書き込み用ストリームを開く PrintWriter pw = new PrintWriter(uc.getOutputStream()); // CGIにデータを送信する pw.print(data); // ストリームを閉じる pw.close(); // CGIからの読み込み用ストリームを開く BufferedReader br = new BufferedReader( new InputStreamReader(uc.getInputStream())); // CGIの出力を読み込んでコンソール画面に表示 String line = ""; while ((line = br.readLine()) != null) { System.out.println(line); } // ストリームを閉じる br.close(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }
送信するデータはString型で&で区切られた形にしています。
name=もり&score=1500
これは、もりさんのスコアが1500点だというデータです。CGIはこのデータを処理してスコアを保存したり、表示したりします。CGIのアドレスはURLクラスで表します。
URL cgiURL = new URL("http://javagame.main.jp/cgi-bin/score/send_score.cgi");
score.cgiは自作のCGIで私が借りているレンタルサーバ(http://javagame.main.jp/)上に配置してあります。旧ドメインなのでリンク切れです。send_score.cgiに先ほどのデータを送信するわけです。CGIの作り方は次のCGIの構成を見てください。CGIへの接続は、URLConnectionを使います。
URLConnection uc = cgiURL.openConnection();
URLクラスのopenConnection()で接続を開始します。CGIへデータを送信したり、受信したりするためにはストリームを使います。 Javaはファイルへ読み書きするのと同じ方法でネットワークを介したCGIへ読み書きできます。
// CGIへの書き込み用ストリームを開く PrintWriter pw = new PrintWriter(uc.getOutputStream()); // CGIにデータを送信する pw.print(data);
文字列を読み書きしたいのでPrintWriterを使います。URLConnectionのgetOutputStream()で開いたストリームをPrintWriterに渡すだけです。CGIへデータを送信するにはこのストリームにデータをprint()するだけです。一般的にCGIは何らかのデータ(普通はHTML)を返してきます。その返されたデータを受け取ってあげましょう。
BufferedReader br = new BufferedReader(new InputStreamReader(uc.getInputStream())); // CGIの出力を読み込んでコンソール画面に表示 String line = ""; while ((line = br.readLine()) != null) { System.out.println(line); }
読み込みにはBufferedReaderを使います。URLConnectionのgetInputStream()で開いたストリームを InputStreamReader()を通してBufferedReaderに渡します。ファイルから読み込むときと似てますね。CGIからデータを受信するにはファイルと同じくreadLine()を使って1行ずつ読み込みます。ここでは単純に画面に出力しています。
CGIの構成
このサイトはJavaがメインなのでPerlについては特に解説しません。Perlについて詳しく知りたい方はPerlプログラミング講座や初めてのPerlを読んでください。
- 作者: Randal L. Schwartz,brian d foy,Tom Phoenix,近藤嘉雪
- 出版社/メーカー: オライリージャパン
- 発売日: 2012/07/25
- メディア: 大型本
- 購入: 7人 クリック: 22回
- この商品を含むブログ (17件) を見る
CGIもそんなに複雑でないので全コードを掲載します。
#!/usr/bin/perl # 送信されたデータを受け取る if ($ENV{'REQUEST_METHOD'} eq "POST") { read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); } # データを分割する @pairs = split(/&/, $buffer); # 各データをさらに分割して%paramハッシュに入れる foreach $pair (@pairs) { ($key, $value) = split(/=/, $pair); # valueが日本語の場合コード化されているので変換する $value =~ s/%([a-fA-F0-9][a-fA-F-0-9])/pack("C", hex($1))/eg; $param{$key} = $value; } # 出力されるHTML print <<END; Content-type: text/html <html> <head><title>あなたの得点は登録されました</title></head> <body> <h1>あなたの得点は登録されました</h1> <p>$param{name}さんは$param{score}点です。</p> </body> </html> END
CGIは大きく分けると
- データを受信する
- 受信したデータを処理する
- HTMLを送り返す
となっています。上にあげたサンプルも3つに分割できます。まずデータを受信するところです。
# 送信されたデータを受け取る if ($ENV{'REQUEST_METHOD'} eq "POST") { read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); }
まあこれはこう書くものと思ってもらっていいと思います。CGIへのデータ送信方法はGETとPOSTという2種類があるんですが、ここでは POSTの方を使っています。Javaから送ったname=もり&score=1500という文字列が$bufferに入ることだけわかればいいと思います。次にデータ処理部分です。
@pairs = split(/&/, $buffer);
は、name=もり&score=1500を&で分割して、name=もりとscore=1500を配列@pairsに入れています。そして、
foreach $pair (@pairs) { ($key, $value) = split(/=/, $pair); # valueが日本語の場合コード化されているので変換する $value =~ s/%([a-fA-F0-9][a-fA-F-0-9])/pack("C", hex($1))/eg; $param{$key} = $value; }
の部分で、name=もりをさらに分割してハッシュ%paramを作ってます。
ハッシュ%param name => もり score => 1500
というハッシュです。Perlではハッシュをよく使うのでわからない方は上のリンク先で調べてみてください。最後にHTMLを生成してJavaプログラムに返します。
# 出力されるHTML print <<END; Content-type: text/html <html> <head><title>あなたの得点は登録されました</title></head> <body> <h1>あなたの得点は登録されました</h1> <p>$param{name}さんは$param{score}点です。</p> </body> </html> END
$param{name}が「もり」に、$param{score}が「1500」に置き換わったHTMLになります。実際にプログラムを実行すると画面にこのHTMLが表示されることがわかります。
最後にこのCGIをサーバーにアップします。ご自分でサーバーを持っている場合はアップしてみてください。このとき、CGIのパーミッションを実行可能(755)にしとかないと正しく動きません。結構忘れがちなので注意です。
「あなたの得点は登録されました」とか書いてありますが、登録してません(笑)もしスコアを登録(保存)したい場合はこのCGIを改造する必要があります。HTMLを返す前にファイルを開いてスコアをファイルに書き込む処理をはさむだけです。次回取り上げます。