JavaでのGAE(Google App Engine)開発を行う場合、特に意識しなければフロントエンドはjspにするのが自然の流れかと思うのですが、
- できるだけサーバでの処理は少なくしたい
- サーバでの処理量・使用リソース量に比例してコストも上がるので
- 静的コンテンツなら、レスポンス速度の早い別サーバ(staticサーバ)から受け取ることができる
- 動的に生成されるコンテンツであるjspに対して、htmlやJavaScriptは静的コンテンツである(もちろん画像ファイルなども)
- つまり、htmlとJavaScript(Ajax)でコンテンツを構成するほうが、jspで同様のことをするよりもUX向上の点で有利
といった理由から、今やセオリーは「フロントエンドはHTMLとJavaScript(Ajax)で構成」「サーバ側は、フロントエンドからのAjaxリクエストに対してJson形式でデータを返す」という構成になっているようです。(ぼくの自己紹介ページ・えいのうのいえも、この構成で作ってみています。)
で、サーバ側がJson形式のデータを返す方法は、まぁ色々とあると思うんですが、Slim3のJson形式への変換機能がお手軽です。 流れとしては、以下のようなかんじ。
- Json形式で返したいデータの構造を持ったModelクラスをつくる
- 返送データをModelクラスにセットするよう、アプリケーション内で記述する
- ModelクラスからJson形式への変換を行う
- クライアントへのレスポンスにJson形式データを書き込む
では、ひとつずつ。
Json形式で返したいデータの構造を持ったModelクラスをつくる
例えば、とあるWebアプリケーションにおいて、「いつ」「だれが」「どうした」というようなアクティビティの情報をクライアントに返送したい、といった場合を想定します。 そのとき、「Json形式で返したいデータの構造を持ったModelクラス」は、以下のようになります。
@Model public class ActivityInfo { @Attribute(primaryKey = true) @Json(ignore = true) Key key; //いつ Date date; //だれが String loginID; //どうした(0:ユーザー新規登録, 1:日記更新, 2:プロフィール更新) int activityCode; //以下アクセサ(省略) }
Modelクラスなので、主キー用のフィールドを宣言しておかなくてはならないのですが、クライアントに返すJsonデータとしては、その情報は不要なわけです。そういったフィールドには、アノテーション「@Json(ignore = true)」を付加しておくことで、Json形式への変換対象から、そのフィールドは無視されるようになります。
返送データをModelクラスにセットするよう、アプリケーション内で記述する
これはもう、普通にやってやればOKです。
ActivityInfo activityInfo = new ActivityInfo(); activityInfo.setDate(new Date()); activityInfo.setLoginID("a-know"); activityInfo.setActivityCode(1);
こんなかんじで。
ModelクラスからJson形式への変換を行う
クライアントへのレスポンスにJson形式データを書き込む
最後のふたつは、一気にやってしまいます。
response.setCharacterEncoding("utf-8"); response.setContentType("application/json"); response.getWriter().println(ActivityInfoMeta.get().modelToJson(activityInfo)); response.flushBuffer();
ここでのresponseは、Controllerを継承したControllerクラスがフィールドとして持っているresponse、HttpServletResponseです。
ActivityInfoMetaはSlim3のAPT機能により、Modelクラス・ActivityInfoを作った時点で自動的に作られているとおもいます(Eclipse + Slim3プラグイン)。 そのActivityInfoMeta.modelToJson()を使用してやることで、ModelクラスをJson形式文字列へと簡単に変換してやることができます(複数のModelクラスをJson形式に変換できるmodelsToJson()もあります)。 なので、この文字列をresponse.getWriter().println()、response.flushBuffer()を使って書き込んでやります。
あとはJavaScript(Ajax)で受け取るだけ!
こんなかんじ。(上記処理を行なっているのが、ActivityControllerだとした場合。)
$.ajax({ url: '/activity', type: 'get' }).success(onSuccess).error(onError);
Ajaxによる通信・その後の描画完了までの間は、なにかしらローディング中であることがわかるGIFアニメーションかなんかを表示しておいてやるのが良さそうですね!(参考:かなりかっこいいデザインのローディング用アニメーションを生成するスクリプト -Sonic)
Google API Expertが解説する Google App Engine for Java実践ガイド
- 作者: 小川信一
- 出版社/メーカー: インプレス
- 発売日: 2012/03/16
- メディア: 大型本
- クリック: 12回
- この商品を含むブログ (14件) を見る