えいのうにっき

主に Web 系技術ネタ。背景画像 is powered by grass-graph.shitemil.works

GAE/J + Slim3 で、Json形式のデータをクライアントにお手軽に返す方法

JavaでのGAE(Google App Engine)開発を行う場合、特に意識しなければフロントエンドはjspにするのが自然の流れかと思うのですが、

  • できるだけサーバでの処理は少なくしたい
    • サーバでの処理量・使用リソース量に比例してコストも上がるので
  • 静的コンテンツなら、レスポンス速度の早い別サーバ(staticサーバ)から受け取ることができる
    • 動的に生成されるコンテンツであるjspに対して、htmlやJavaScriptは静的コンテンツである(もちろん画像ファイルなども)
  • つまり、htmlとJavaScriptAjax)でコンテンツを構成するほうが、jspで同様のことをするよりもUX向上の点で有利


といった理由から、今やセオリーは「フロントエンドはHTMLとJavaScript(Ajax)で構成」「サーバ側は、フロントエンドからのAjaxリクエストに対してJson形式でデータを返す」という構成になっているようです。(ぼくの自己紹介ページ・えいのうのいえも、この構成で作ってみています。)




で、サーバ側がJson形式のデータを返す方法は、まぁ色々とあると思うんですが、Slim3Json形式への変換機能がお手軽です。
流れとしては、以下のようなかんじ。

  • 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実践ガイド

Google API Expertが解説する Google App Engine for Java実践ガイド





follow us in feedly