2.1のチュートリアルを試してみています。関する記事の一覧JSONPでデータが取得できるところまで、前回試してみました。その2今回は、JSONPで取得したデータを全てオブジェクトに格納してみます。requestsこちらを参考に、プログラムを作成しました。前回は、一番変換が簡単そうなデータだけ取得してみました。count(ブックマークしている合計ユーザ数)url(ブックマークされているURL)title(タイトル)eid(エントリーID)entry_url(はてなブックマークエントリーページのURL)screenshot(スクリーンショット画像のURL)今回は、配列で定義されている「bookmarks」のデータを取得してみます。bookmarks配列の個々の内容はこんな感じになります。comment(コメント)timestamp(ブックマークした時刻)user(ブックマークしたユーザ名)tags(タグの配列)かなり手探りでしたが、まずbookmarks配列用のオブジェクトを定義しました。パッケージ・エクスプローラーで「com.fc2.blog68.symfoware.hatena.client」を選択した状態でEclipseの[ファイル]-[新規]-[クラス]を選択。名前に「HatenaBookmarkData」スーパークラスに「com.google.gwt.core.client.JavaScriptObject」と入力して、完了を押下します。クラスの内容は以下のとおり。}-*/;}タグの配列は、文字列の配列となるのですが、この戻り値に何を指定すればよいかわからずはまりました。最初、戻り値をString[]としていたのですが、これだとオブジェクト変換時にエラーになります。「com.google.gwt.core.client.JsArrayString」を使えばJSONの文字列配列を表現できるようです。前回作成した「HatenaData」クラスにブックマークの配列を取得するためのメソッド「getBookmarks()」を追加します。}-*/;}getBookmarks()の戻り値を以下のように定義するのがミソ。JsArray<HatenaBookmarkData>テーブルにデータを表示する処理これでデータの取得と変換が行えるようになりました。テーブルに取得したデータを表示する処理を追加します。jso;}-*/;}開発用のサーバーを起動して実行してみると非常に画面が地味ですが、ちゃんと情報を取得できていることが確認できました。2.1のチュートリアルを試してみています。雛形で生成されたプログラムを変更するところまで、前回試してみました。その1今回は、JSONPでデータを取得するロジックを考えたいと思います。requestsこちらを参考に、プログラムを作成しました。取得したデータを解析し、オブジェクトに変換するためのJavaScriptObjectを継承したクラスを作成します。パッケージ・エクスプローラーで「com.fc2.blog68.symfoware.hatena.client」を選択状態にしておき、[ファイル]-[新規作成]-[クラス]を選択。クラス名を「HatenaData」スーパークラスに「com.google.gwt.core.client.JavaScriptObject」を入力して、完了を押下。上位にある変換が簡単そうなデータから。以下の情報をJSON形式のデータからマッピングするクラスを作成してみます。count(ブックマークしている合計ユーザ数)url(ブックマークされているURL)title(タイトル)eid(エントリーID)entry_url(はてなブックマークエントリーページのURL)screenshot(スクリーンショット画像のURL)「HatenaData.java」の内容はこんな感じになりました。入力されたURLをパラメーターに付加し、JSON形式のデータを取得できるようにします。内容の詳細を理解できていませんが・・・参考サイトに記載されているソースから試行錯誤して作成したソースがこちら。jso;}-*/;}ちゃんとデータの取得と変換が行われれば、デバッグ用に用意したラベルに・はてなブックマークエントリーページのURL・タイトル・ブックマークされている件数が表示されるはずです。実行結果ここまでで、開発用のサーバーを起動し、動作を確認してみました。検索ボタンを押すと、狙い通りの情報が表示されました。次は、配列として格納されているbookmarksを変換する方法について考えてみることにします。2.1のチュートリアルを試してみています。前回はJSONを使用したクライアントとサーバー間の通信を試しました。今回は、JSONPでのデータ取得を試してみます。requestsこちらを参考に、プログラムを作成しました。design参考にしたサイトでは、JSONPで返却する値を検討しています。今回は、はてなブックマークのエントリー情報を取得するJSONPが公開されていますので、それにアクセスしデータを取得・表示するサンプルを作成してみようと思います。はてなブックマークエントリー情報取得APIこちらのサイトを参考にさせていただきました。Testでの実行結果を見たほうが返却されるデータ形式の理解が早いかと思います。上位にcount(ブックマークしている合計ユーザ数)url(ブックマークされているURL)bookmarks(ユーザがブックマークしたデータの配列)title(タイトル)eid(エントリーID)entry_url(はてなブックマークエントリーページのURL)screenshot(スクリーンショット画像のURL)という情報が並びます。bookmarks配列のないようはこんな感じになるようです。comment(ブックマークコメント)timestamp(ブックマークした時刻)user(ブックマークしたユーザ名)tags(タグの配列)受け取り用のオブジェクトを定義するときの参考になりそうです。source参考にしたサイトでは、仕様を満たすサーバーサイドのソースコードについて解説されていますが、ここでは、はてなAPIに送るリクエストについて考えて見ます。いっても簡単でhttp://b.hatena.ne.jp/entry/json/?url=[取得したいサイトのURL]&callback=[コールバック関数]という形式でGETリクエストを送信すればよいようです。serverこれまで、「StockWatcher」というプロジェクトを作成し、徐々に機能追加を行う形で学習してきました。復習の意味もこめて、新しくプロジェクトを作成し、プログラムを作成することにしました。2.1のプラグインをインストールしておきます。2.1のEclipseプラグインをインストールするEclipseツールバーのアイコンをクリック。プロジェクト名を「hatena」パッケージを「com.fc2.blog68.symfoware.hatena」として、プロジェクトを新規作成します。雛形のファイルが作成されますが、以下のクラスは不要なので削除しました。com.fc2.blog68.symfoware.hatena.client.GreetingServicecom.fc2.blog68.symfoware.hatena.client.GreetingServiceAsynccom.fc2.blog68.symfoware.hatena.server.GreetingServiceImplcom.fc2.blog68.symfoware.hatena.shared.FieldVerifierパッケージ・エクスプローラーでの表示です。選択状態にあるソースを削除しました。Hatena.gwt.xmlの編集HTTPリクエストを行ううえで後々必要になると思いますので、Hatena.gwt.xmlに一行「com.google.gwt.http.HTTP」を使用する設定を追記しておきます。以下、パッケージ・エクスプローラー上からみた「Hatena.gwt.xml」の場所と、Hatena.gwt.xmlの記載内容です。path='shared'/></module>Hatena.htmlの編集Hatena.htmlを雛形の状態から編集しました。idが「rootPanel」という名前のdivを追加し、プログラム中からここへ部品を配置することにします。パッケージ・エクスプローラー上での「Hatena.html」の場所と記載内容は以下のとおり。雛形として出力されたweb.xmlにはサーブレットに関する記載がありますが、先ほどざっくり消しましたので、このまま起動しようとするとエラーになってしまいます。web.xmlのサーブレットに関する指定を消しておきます。パッケージ・エクスプローラー上での場所と内容は以下のとおり。--><welcome-file-list><welcome-file>Hatena.html</welcome-file></welcome-file-list></web-app>Hatena.javaの編集ここまでで下準備は整いました。メインのHatena.javaを編集します。チュートリアルに沿わない状態でプログラムを作成しているので、まずは・検索するURLを記載するテキストボックス(findText)・検索実行ボタン(findButton)・結果を表示するテーブル(stocksFlexTable)これらを配置するだけのプログラムを書いてみました。パッケージ・エクスプローラー上での「Hatena.java」の位置と記載内容は以下のとおり。初期フォーカスは、検索URL入力テキストに設定findText.setFocus(true);}}ここまでで、デバッグ用のサーバーを起動して動作を確認しました。起動は、実行ボタンの右側にある下矢印を押すと、「hatena」という項目が追加されていますので、これを選択します。サーバー起動後、http://127.0.0.1:8888/Hatena.html?gwt.codesvr=127.0.0.1:9997にアクセスすると、こんな表示になりました。ここまでは狙い通り動いてくれているようです。2.1のチュートリアルを試してみています。RPCを使用したクライアントとサーバー間の通信を試しました。RPCではなく普通のJSON形式のデータを取り扱う方法を試して見ます。Dataこちらを参考に、プログラムを作成しました。dataStockWatcher.javaのrefreshWatchListメソッドで、株価をランダムに生成しています。RPCを使用してサーバー側で株価を生成するように変更しました。今回は、株価をJavaのサーブレットで作成し、JSON形式のレスポンスを作成。クライアント側のJavaScriptで解析し表示するように変更します。パッケージ・エクスプローラーの「com.google.gwt.sample.stockwatcher.client」を選択した状態で、Eclipseのツールバーの[ファイル]-[新規]-[クラス]を選択します。パッケージ名を「com.google.gwt.sample.stockwatcher.server」に変更クラス名を「JsonStockData」として、完了ボタンを押下。新しいクラスを作成します。作成した「JsonStockData」を以下の内容に変更します。},");}out.println(']');out.flush();}}このサーブレットにアクセスできるよう、WEB-INF/web.xmlを編集します。--><welcome-file-list><welcome-file>StockWatcher.html</welcome-file></welcome-file-list></web-app>ここまでで、JSONデータの取得が行えるようになっているはずです。ブラウザでhttp://localhost:8888/stockwatcher/stockPrices?q=ABC+DEFを表示すると、こんな結果が得られると思います。codeまず、JSONデータをラップするためのクラスを作成します。「com.google.gwt.sample.stockwatcher.client」を選択した状態で、Eclipseのツールバーの[ファイル]-[新規作成]-[クラス]を選択。パッケージは「com.google.gwt.sample.stockwatcher.client」クラス名は「StockData」スーパークラスは「com.google.gwt.core.client.JavaScriptObject」として、完了を押下します。作成した「StockData」を以下の内容で更新します。0.18992536537119453}この部分に割り当てられるイメージでよいかな?と思っています。requestsまず、StockWatcher.gwt.xmlに変更を加えます。path='shared'/></module>「com.google.gwt.http.HTTP」の記載を追加することで、サーバー側とのHTTP通信が行えるようになるようです。※雛形のJavaScriptにメソッドが追加出力されるようになる?次に、StockWatcher.javaに以下のimportを追加。"stockPrices?q=";株価データの取得を行うメソッド「refreshWatchList」を変更します。JSON");}}取得したJSON形式のデータを配列に変換するメソッドを追加。eval(json);}-*/;updateTableの引数を、「StockPrice[]」から「JsArray<StockData>」に変更します。エラーメッセージ領域を非表示にするerrorMsgLabel.setVisible(false);}もう一箇所、updateTableの引数「StockPrice」を「StockData」に変更。errorsエラーメッセージ表示用のメソッド「displayError」を定義します。RPCからJSONへの変更は完了です。開発用のサーバーを起動して、ブラウザからアクセスすると従来どおりの表示が行われているはず。最終的に、StockWatcher.javaはこうなりました。ルートパネルとして取得し、mainPanelを設定する。不正な証券コードです。追加予定の証券コードが既にリストに含まれていたら、追加処理を実行しない。ラベルに対してテキストを追加するようにする。2.1のチュートリアルを試してみています。簡単なアプリケーションを作成しましたが、クライアント側のJavaScriptの動作で完結する内容でした。実際は、サーバーと通信してデータの取得や登録を行うアプリケーションが多いと思いますので、RPCの使用に関する章も試してみることにします。Callsこちらを参考に、プログラムを作成しました。serviceこれまでのチュートリアルで作成した「StockWatcher」で、株価の値はStockWatcherクラスのrefreshWatchListメソッドでランダムに生成していました。該当する処理の箇所はここ。change);}updateTable(prices);}この部分をサーバー側で処理するように変更します。「RemoteService」を継承して「StockPriceService」を作成します。パッケージ・エクスプローラーで「com.google.gwt.sample.stockwatcher.client」を選択しておきます。Eclipseツールバーの[ファイル]-[新規]-[インターフェース]を選択。名前に「StockPriceService」を入力して「完了」を押します。その他はデフォルトのままでOKStockPriceService.javaを以下の内容に変更します。※変更した時点ではエラーが表示されると思いますが、次のソースを作成することでエラーが解消されますので、一旦無視で。symbols);}次に、「RemoteServiceServlet」を継承したクラスを作成します。Eclipseのツールバーから[ファイル]-[新規]-[クラス]を選択。パッケージ名を「com.google.gwt.sample.stockwatcher.client」から「com.google.gwt.sample.stockwatcher.server」に変更します。名前は「StockPriceServiceImpl」スーパークラスに「com.google.gwt.user.server.rpc.RemoteServiceServlet」を入力します。「com.google.gwt.sample.stockwatcher.client.StockPriceService」を入力し候補を表示。完了ボタンを押下します。Eclipseで自動生成された「StockPriceServiceImpl.java」は以下のようになるはずです。null;}}この「StockPriceServiceImpl」クラスの「getPrices」メソッドにクライアントのJavaScriptで動作していた株価生成の処理を移動します。処理記載後のStockPriceServiceImpl.javaはこうなりました。prices;}}この作成したサービスはservletで動作します。そのため、web.xmlへservletの追加が必要になります。http://localhost:8888/stockwatcher/stockPricesというURLでサービスを公開しようと思いますので、StockWatcher/war/WEB-INF/web.xmlを以下のように編集しておきます。※雛形としてで出力されている「greetServlet」という定義があるかと思いますが、ここで消してしまいます。clientここまでの操作でサーバー側で実行されるプログラムが作成できたことになります。これから、クライアント側からサーバー側に通信するためのプログラムを作成します。前の段落で作成した「StockPriceService」ですが、エラーが表示されている状態だと思います。ソースの左側にある黄色いアイコンをクリックすると、こんな感じで修正候補が表示されるはずです。...」を選択すると、ダイアログが表示されます。そのまま完了を押下して、操作を進めます。自動生成された「StockPriceServiceAsync」は以下のようになるはずです。callback);}クライアント側では、このクラスを経由してサーバー側との通信を実現する模様。StockWatcherクラスに以下のimportを追加。com.google.gwt.user.client.rpc.AsyncCallback;また、以下の変数も追加。GWT.create(StockPriceService.class);refreshWatchListメソッドの処理内容をこのように変更します。callback);}ここまでできたら、開発用のサーバーを起動し、ブラウザでアクセスしてみます。すると、こんな感じでエラーが表示されるはずです。com.google.gwt.sample.stockwatcher.client.StockPrice[])クライアントとサーバー間のデータのやり取りに使用している「StockPrice」をシリアライズできなかったよ。objectsというわけで、データの通信に使用している「StockPrice」をシリアライズ可能とするため、「Serializable」をimplementsするよう変更してやります。StockPriceで変更した箇所の抜粋はこちら。Exceptions最後にエラー処理を追加します。Eclipseのツールバー[ファイル]-[新規]-[クラス]を選択。名前「DelistedException」スーパークラス「java.lang.Exception」インターフェース「java.io.Serializable」を入力し、完了を押下。DelistedExceptionを以下の内容に変更します。this.symbol;}}StockPriceServiceのgetPricesメソッドが作成した例外を投げられるように修正します。株式銘柄コードに「ERR」と入力された場合は、DelistedExceptionを発生するように修正しました。修正後の「StockPriceServiceImpl」はこんな感じになります。prices;}}エラーの表示は赤い文字で行いたいと思いますので、StockWatcher.cssに以下の記載を追加。red;}StockWatcher.javaにエラー表示用のラベルを追加します。Label();作成したラベルオブジェクトをパネルに配置する処理も追加。最終更新日ラベルを追加mainPanel.add(errorMsgLabel);mainPanel.add(stocksFlexTable);mainPanel.add(addPanel);mainPanel.add(lastUpdatedLabel);refreshWatchListメソッドでTODOとして残していた、onFailureの処理を追記。サーバー側で発生したエラーをラベルに出力します。callback);}このままだと、一度エラーが発生した後はずっとエラーの表示が残ってしまうため、エラー表示を消去する処理を追加します。狙い通りの動きになっているかと思います。次のページプロフィールAuthor:symfoblog形式だと探しにくいので、まとめサイト作成中です。