月別: 2011年3月

Reference Guide (v1.2)(Google Sites Data API)

android用の神経衰弱ゲームを公開しました(・∀・)
The Match-up(Memory) game for android was released!

Google Play:
Mole's Match-up.

Introduction page:
Mole’s Match-upをリリースした∩( ・ω・)∩


http://code.google.com/intl/ja/apis/sites/docs/1.0/reference.html

 Reference Guide (v1.2)

このドキュメントはGoogle Site Data APIの生のプロトコル(XMLとHTTP)についての詳しい参考文書(リファレンス文書)を提供します。このドキュメントはプログラミング言語用クライアントライブラリについての情報を含んでいません。クライアントライブラリのリファレンス情報については、デベロッパガイドのプログラミング言語別のセクションのリンク先を見てください。

 内容

 対象読者

このドキュメントはGoogleサイトと対話することが出来るクライアントアプリケーションを作成したいプログラマーを対象としています。
参考文書です; Developer’s Guideで示される概念と Google Data APIs protocolの背後にある大まかな考えを理解していると仮定します。

 Google サイト フィード タイプ

Google Sites Data API は以下のタイプのフィードを提供します:

アクティビティフィード

アクティビティフィードはサイト内の全てのアクティビティ(活動)を包含するフィードです。
特定のドメイン内にあるサイト用のこのフィードの GET URI は:

https://sites.google.com/feeds/activity/domainName/siteName/[activityEntryID]

domainName は”site”またはGoogle Apps ドメインのどちらかです。
siteName はサイトのランディングページのURLに現れるサイトの名前です。: http://sites.google.com/a/domainName/siteName/.
このフィードへの全てのリクエストは認証されていないといけません。
サポートされているリクエストタイプ: GET

コンテントフィード

コンテントフィードは現在の編集可能なサイトのコンテント(内容)を包含するフィードです。
特定のドメイン内にあるサイト用のこのフィードの GET URI は:

https://sites.google.com/feeds/content/domainName/siteName/[contentEntryID]

domainName は”site”またはGoogle Apps ドメインのどちらかです。
siteName はサイトのランディングページのURLに現れるサイトの名前です。: http://sites.google.com/a/domainName/siteName/.
このフィードへのリクエストはサイトの(公開)設定によっては認証が必要です。
サポートされているリクエストタイプ:  GETPOSTPUTDELETE
標準データAPIクエリパラメータに加えて、SiteデータAPIは以下のオプションパラメータがコンテントフィードを使用して  GET リクエストを出すことを可能にします?
パラメータ 説明 Notes
ancestor 指定したアンセスター(祖先)を持つエントリのみをリクエストします。 string 希望のアンセスターエントリのIDを提供します。
例えば:0123456789。ペアレント(親)、ペアレントの
ペアレントのように、指定したアンセスターを持つ
全てのエントリを返します。
include-deleted 削除されたエントリを含むかどうか指定します。 boolean 指定可能な値はtrue または falseです。
デフォルトではfalseです。
include-draft ドラフト(下書き)エントリを含むかどうかを指定します。 boolean 指定可能な値はtrue または falseです。
デフォルトではfalseです。
対象となるドラフトの所有者か著作者(author)
である必要があります。
kind 返されるコンテントエントリの種類を指定します。これらは右に挙げるGoogleサイト内のページタイプです。 カンマで区切られた文字列のリスト 指定可能な値は announcement,
announcementspage,attachment,
commentfilecabinet,
listitemlistpage,webpage,
webattachmenttemplateです。
parent 指定したペアレントを持つエントリのみをリクエストします。 string ペアレントエントリのIDを
提供します。例えば: 0123456789.
path あるページ階層下にある内容をリクエストします。 string 内容を取得して来るサイト内の
サブページへのパス。
例えば: path=/path/to/page.

リビジョンフィード

リビジョンフィードはサイトコンテントの改訂(リビジョン)履歴を包含したフィードです。
特定のドメイン内にあるサイト用のこのフィードの GET URI は:

https://sites.google.com/feeds/revision/domainName/siteName/contentEntryID/[revisionEntryID]



domainName は”site”またはGoogle Apps ドメインのどちらかです。


siteName はサイトのランディングページのURLに現れるサイトの名前です。: http://sites.google.com/a/domainName/siteName/.

このフィードへの全てのリクエストは認証されていないといけません。
サポートされているリクエストタイプ: GET



サイトフィード

サイトフィードはユーザーが所有または閲覧許可を持つGoogleサイトを一覧にするために使用できます。更にサイトフィードは既存サイトの名前変更、サイトのコピー、新しいサイトの作成のために使用できます。
サイト一覧用のフィードURIは:

https://sites.google.com/feeds/site/domainName/[siteName]
domainName は”site”またはGoogle Apps ドメインのどちらかです。

このフィードへの全てのリクエストは認証されていないといけません。

サポートされているリクエストタイプ:  GETPOSTPUT

サイトフィードはサイトを一覧するための GET リクエストを発生させる時、以下の(任意の)パラメータをサポートします:
パラメータ 説明 Notes
include-all-sites 少なくともGoogle Appsドメイン内でユーザーが観ることが出来る全てのサイトを一覧にします。 boolean GoogleAppsドメインのサイトを一覧にする場合にのみ
このパラメータは利用出来ます。
指定可能な値はtrueまたはfalseです。
デフォルトではfalseです。
with-mappings サイトエントリ内にwebアドレスマッチングを含むかどうか。 boolean 指定可能な値はtrueまたはfalseです。
デフォルトで
falseです。

ACL フィード

ACLフィードはGoogleサイトの共有パーミッション(ACLs)を変更するためや一覧にするために使用できます。
サイト一覧用のフィードURIは:

https://sites.google.com/feeds/acl/site/domainName/siteName/[aclEntryID]



domainName は”site”またはGoogle Apps ドメインのどちらかです。

このフィードへの全てのリクエストは認証されていないといけません。

サポートされているリクエストタイプ:  GETPOSTPUTDELETE

 Google Sites クエリパラメータリファレンス

Google Data API プロトコルのクエリパラメータをサポートします:
  • author
  • max-results
  • published-max (only content feed)
  • published-min (only content feed)
  • start-index
  • updated-max
  • updated-min
  • q (full text-queries)
フィード特有のパラメータのリストについては上記のそれぞれのフィード を見てください。.

Making Remote Procedure Calls

android用の神経衰弱ゲームを公開しました(・∀・)
The Match-up(Memory) game for android was released!

Google Play:
Mole's Match-up.

Introduction page:
Mole’s Match-upをリリースした∩( ・ω・)∩


http://code.google.com/intl/ja/webtoolkit/doc/latest/tutorial/RPC.html

 

 リモートプロシージャコールの作成

この時点でクライアントサイドのコードで株価データをシミュレートするストックウォッチャー(株価監視)アプリケーションの最初の実装を作成しています?
このセクションでは株価データを返すサーバサイドメソッドへのGWTリモートプロシージャコールを作成します。クライアントから呼び出されるサーバサイドコードはサービスとしても知られます;リモートプロシージャコールを作成するという行為はサービス呼び出しと呼ばれます。
あなたが学ぶであろうことは:
  1. サーバでのサービスの作成
  2. クライアントからのサービス呼び出し
  3. データオブジェクトのシリアライズ(直列化)
  4. 例外処理: チェックされる例外と予期されない例外
Note: GWTアプリケーションでのRPC通信のより広いガイドについてはCommunicate with a Server – Remote Procedure Callsを見てください。

 始める前に

StockWatcher プロジェクト

このチュートリアルはGWTの概念とBuild a Sample GWT Application チュートリアルで作成したStockWatcherアプリケーションを基にしています。 もしGWTアプリケーション作成チュートリアルを終えておらずGWTの概念がある程度わかっているなら(慣れ親しんでいるなら)、ここでStockWatcherプロジェクトをコードとしてインポートすることが出来ます。
  1. StockWatcher projectをダウンロードします。
  2. ファイルを解凍します。
  3. Eclipse へプロジェクトをインポートします。
    1. ファイル メニューから、インポートメニューオプションを選択します。
    2. [一般]-[既存プロジェクトをワークスペースへ]を選択します。次へ(N)ボタンをクリックします。
    3. [ルート・ディレクトリーの選択(T)]でブラウズしStockWatcherのあるディレクトリ(ファイルを解凍した場所から)を選択します。完了(F) ボタンをクリックします。
antを使用している場合は、StockWatcher/build.xmlの何処にGWTを解凍したかを指す gwt.sdk プロパティを編集します

 GWT RPCとは何か?

GWT RPCフレームワークはwebアプリケーションのクライアントとサーバのコンポーネント間でHTTPを利用したJavaオブジェクトを交換することを簡単にします。 クライアントから呼び出されるサーバサイドのコードはしばしばサービスと呼ばれます。GWT RPCサービスの実装は周知のJavaサーブレットアーキテクチャに基づいています。クライアントコード内で、サービスの呼び出しを作成するために自動生成プロクシクラスを使用します。GWTは前後に渡される-メソッド呼び出しと返り値での引数-Javaオブジェクトのシリアライゼーションを処理します?
Important: GWT RPCサービスはSOAPまたはRESTに基づくwebサービスと同じではありません。 これらは単にサーバとクライアント上のGWTアプリケーション間のデータ転送のための軽量な方法です。 アプリケーションへGWT RPCサービスを統合するための単一層と多層のデプロイメントオプションを比較するために? デベロッパガイド Architectural Perspectivesを見てください。

 GWT RPCメカニズムでのJavaコンポーネント

GWT RPCをセットアップする時, リモートサーバ上で動作しているプロシージャの呼び出しに関係する三つの要素に注目します。
  • サーバ上で動作しているサービス(呼び出すメソッド)
  • サービスと関係するクライアントコード
  • クライアント-サーバ間で渡されるJavaデータオブジェクト
    データオブジェクトをサーバ-クライアント間で任意のテキストとして渡すことが出来るようにサーバとクライアントはどちらもデータをシリアル化/デシリアル化する機能を持ちます。

GWT RPC Plumbing

RPCインターフェイスを定義する為に、三つのコンポーネントを書く必要があります:
  1. サービス用のRemoteServicesを継承するインターフェイス(StockPriceService)を定義し、全てのRPCメソッドをリストします。(※サービスインターフェイス)
  2. RemoteServiceServletを継承したクラス(StockPriceServiceImpl)を作成し、1.で作成したインターフェイスをimplementsします。(※サービス実装)
  3. クライアントサイドコードから呼び出されるサービスへの非同期インターフェイス(StockPriceServiceAsync)を定義します。(※サービスインターフェイスの非同期バージョン)
サービス実装はRemoteServiceServletを継承しなければならず、関連するサービスインターフェイスをimplementsしなければなりません。サービス実装はサービスインターフェイスの非同期バージョンをimplementsしないことに注意してください。全てのサービス実装は結局はサーブレットですが、HttpServletを継承するのではなく、代わりにRemoteServiceServletを継承します。RemoteServiceServletは自動的にクライアント-サーバ間で渡され、サービス実装で意図されたメソッドで呼び出されるデータのシリアル化を自動的に処理します。

 1. サーバでのサービスの作成

このチュートリアルでは、refreshWatchListのメソッドにある機能を取り出しクライアントからサーバへ移動します。 現在、refreshWatchListのメソッドへ株のシンボルの配列を渡し、メソッドは一致する株データを返します。それから株データを持つフレックステーブルを配置するためにupdateTableメソッドを呼びます。

現在のクライアントサイドの実装:

/**
   * Generate random stock prices.
   */
  private void refreshWatchList() {
    final double MAX_PRICE = 100.0; // $100.00
    final double MAX_PRICE_CHANGE = 0.02; // +/- 2%

StockPrice[] prices = new StockPrice[stocks.size()];
for (int i = 0; i < stocks.size(); i++) {
double price = Random.nextDouble() * MAX_PRICE;
double change = price * MAX_PRICE_CHANGE
* (Random.nextDouble() * 2.0 – 1.0);

prices[i] = new StockPrice(stocks.get(i), price, change);
}

updateTable(prices);
}

 

サービスを作成するために、あなたは:
  1. サービスインターフェイスを定義します: StockPriceService
  2. サービスを実装します: StockPriceServiceImpl

サービスの定義: StockPriceService インターフェイス

GWTにおいて、RPCサービスはGWT RemoteServiceインターフェイスを継承したインターフェイスによって定義されます。StockPriceServiceインターフェイスに対して、メソッドを一つだけ定義する必要があります:このメソッドは株のシンボルの配列を受け入れ、StockPriceオブジェクトとして全ての株に関連付けられたデータを返します。
  1. クライアントサブパッケージで、インターフェイスを作成しStockPriceServiceと名づけます。
    Eclipseでは、パッケージエクスプローラペインで次のパッケージを選択します。
    com.google.gwt.sample.stockwatcher.client
    Eclipseのメニューバーから[ファイル(F)]-[新規(N)]-[インターフェイス]を選択します。
    Eclipseは”新規 Java インターフェイス”ウィンドウを開きます。
  2. “新規 Java インターフェイス”ウィンドウを埋めます。
    [名前(M)]にStockPriceServiceと入力します。
    その他のフィールドはデフォルト値を受け入れます。
    完了(F)ボタンを押します。
    EclipseはStockPriceServiceインターフェイス用のスタブコードを作成します。

    ※”スタブコードはクライアント側で代理オブジェクトを実現する部分である.”

  3. スタブコードを以下のコードに置換えます。
    package com.google.gwt.sample.stockwatcher.client;

import com.google.gwt.user.client.rpc.RemoteService;
import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;

@RemoteServiceRelativePath(“stockPrices”)
public interface StockPriceService extends RemoteService {

StockPrice[] getPrices(String[] symbols);
}

実装での注意: @RemoteServiceRelativePath アノテーションに注意してください。これがサービスとモジュールベースURLと関連するデフォルトパスを結び付けます。

 サービスの実装: StockPriceServiceImplクラス

サーバ上で動作するクラス(StockPriceServiceImpl)を作成します。インターフェイスで定義されているので、 StockPriceServiceImplは一つのメソッドだけ含みます。メソッドは株価データを返します。
これを行うために、GWT RemoteServiceServletクラスも継承したクラスを作成することによって、サービスインターフェイスを実装します。RemoteServiceServletはクライアントから入ってくるリクエストのデシリアライズ(復元)とクライアントへ送るレスポンスのシリアライズ(直列化)の処理を行います。

 

 
サーバサイドコードのパッケージング
サービス実装はサーバでJavaバイトコードとして実行されます;Javaスクリプトへ変換(翻訳)されません。従って、サービス実装はクライアントサイドのコードと同じ言語制約を持ちません。クライアント用コードをサーバ用コードと区別しておくために、別個のパッケージに入れておきます。(com.google.gwt.sample.stockwatcher.server)

新しいクラスの作成

(※ここでの操作指示は開始時にcom.google.gwt.sample.stockwatcher.clientが選択状態であり、

com.google.gwt.sample.stockwatcher.server存在していない前提のようです。)

 
  1. StockPriceService用のサービス実装を作成します。
    エクリプスでは、新規Javaクラスウィザードを起動します。 (ファイル(F) > 新規(N) > クラス)
  2. パッケージ(K)で、.client から .serverへ名前を変更します。
    エクリプスは(実際のクラス作成時に同時に)サーバサイドコード用のパッケージを作成します。
  3. 名前(M)に、 StockPriceServiceImplと入力します。
    実装の注意: 慣例により、サービス実装クラスはサービスインターフェイスの名+接尾辞Implで命名されます。だから、新しいクラスはStockPriceServiceImplとなります。
  4. RemoteServiceServlet クラスを継承します。
    スーパークラス(S)に以下の値を入力します。
    com.google.gwt.user.server.rpc.RemoteServiceServlet
  5. StockPriceService インターフェイスを実装します。
    インターフェイス(I)に、以下のインターフェイスを追加します。
    com.google.gwt.sample.stockwatcher.client.StockPriceService
  6. 抽象メソッドを継承します。
  7. 完了(F)をクリックします。
    エクリプスは以下のパッケージを作成します。
    com.google.gwt.sample.stockwatcher.server
    エクリプスはスタブであるStockPriceServiceImpl クラスを作成します。
    package com.google.gwt.sample.stockwatcher.server;

import com.google.gwt.sample.stockwatcher.client.StockPrice;
import com.google.gwt.sample.stockwatcher.client.StockPriceService;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;

public class StockPriceServiceImpl extends RemoteServiceServlet implements StockPriceService {

public StockPrice[] getPrices(String[] symbols) {
// TODO Auto-generated method stub
return null;
}

}

サーバサイドの実装を記述する

ランダムな株価を返すクライアントサイド実装を置換えます。
  1. 価格と変更データを初期化するためのインスタンス変数を作成します。
    private static final double MAX_PRICE = 100.0; // $100.00
      private static final double MAX_PRICE_CHANGE = 0.02; // +/- 2%
  2. TODO部分を以下のコードに置換えます。nullではなく価格を返します。
    public StockPrice[] getPrices(String[] symbols) {
        Random rnd = new Random();

StockPrice[] prices = new StockPrice[symbols.length];
for (int i=0; i
double price = rnd.nextDouble() * MAX_PRICE;
double change = price * MAX_PRICE_CHANGE * (rnd.nextDouble() * 2f – 1f);

prices[i] = new StockPrice(symbols[i], price, change);
}

return prices;
}

エクリプスはRandomに目印を付け(赤波下線エラー)、import宣言を追加するよう提案します。

 

  • com.google.gwt.user.client.ではなく、java.utilのimport宣言を追加します。
    import java.util.Random;
    実装の注意: サービス実装はサーバ上でJavaバイトコードとして実行されるので、Javaスクリプトに変換出来るかどうか悩むことなく、いかなるJavaクラスまたはライブラリを使用できることを思い出してください。このケースではエミュレートされたGWTバージョン(com.google.gwt.user.client.Random)の代わりにJava runtime library (java.util.Random)のRandomクラスを使用することが出来ます。
  • このリストは完成したStockPriceServiceImplクラスを示します。
    package com.google.gwt.sample.stockwatcher.server;

 

import com.google.gwt.sample.stockwatcher.client.StockPrice;
import com.google.gwt.sample.stockwatcher.client.StockPriceService;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;

import java.util.Random;

public class StockPriceServiceImpl extends RemoteServiceServlet implements StockPriceService {

private static final double MAX_PRICE = 100.0; // $100.00
private static final double MAX_PRICE_CHANGE = 0.02; // +/- 2%

public StockPrice[] getPrices(String[] symbols) {
Random rnd = new Random();

StockPrice[] prices = new StockPrice[symbols.length];
for (int i=0; i
double price = rnd.nextDouble() * MAX_PRICE;
double change = price * MAX_PRICE_CHANGE * (rnd.nextDouble() * 2f – 1f);

prices[i] = new StockPrice(symbols[i], price, change);
}

return prices;
}

}

サーバサイドコードをGWTモジュールに追加する

組み込みサーブレットコンテナ(Jetty)はサービス実装を含むサーブレットをホストすることができます。これはサーバサイドのJavaコードをテストしたりデバッグしている間は開発モードでのアプリケーションの実行を利用することが出来るということを意味します。
これを設定をする為に配備記述子(web.xml)へとの要素を追加し、実装クラス (StockPriceServiceImpl)を指定します。
GWT 1.6で始める場合、サーブレットはGWTモジュール(StockWatcher.gwt.xml)の代わりに配備記述子(web.xml)で定義されるべきです。
要素内で、URLパターンは絶対ディレクトリパスの形式が可能です。(例えば/spellcheck または /common/login)  サービスインターフェイス上で@RemoteServiceRelativePathアノテーションを伴うデフォルトサービスパスを指定した(StockPriceServiceで指定した)場合、url-patternがアノテーションの値と一致するか確かめます。
StockPriceServiceを”stockPrices”へマッピングし、StockWatcher.gwt.xml内の要素のrename-to属性が”stockwatcher”なので、完全なURLは以下のようになります:
http://localhost:8888/stockwatcher/stockPrices
※StockWatcher.gwt.xmlのstockwatcher‘>とweb.xmlの@RemoteServiceRelativePath(“stockPrices“) の緑字部分の連結
  1. 配備記述子を編集します。 (StockWatcher/war/WEB-INF/web.xml)
    greetServletはもはや必要がないので定義を取り除いても大丈夫です。

    
        PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
        "http://java.sun.com/dtd/web-app_2_3.dtd">
    
    
    
      
      
        StockWatcher.html
      
    
      
      
        stockPriceServiceImpl
        com.google.gwt.sample.stockwatcher.server.StockPriceServiceImpl
      
    
      
        stockPriceServiceImpl
        /stockwatcher/stockPrices
      
    
    
    

 2. クライアントからのサービスの呼び出し

サーバへの非同期呼び出しの作成

全てのサービスメソッドへ非同期コールバックパラメータを追加する必要があります。全てのサービスメソッドへ非同期コールバックパラメータを追加するためには以下の新しいインターフェイスを定義しなければなりません:
  • サービスインターフェイスの名前にAsyncを追加した名前を持たなければなりません。(例えば、 StockPriceServiceAsync)
  • サービスインターフェイスと同じパッケージ内に位置していなければなりません。
  • 各メソッドは同じ名前とサービスインターフェイスのものとは重要な違いを備えたシグネチャを持っていなければなりません:メソッドは返り値の型を持たず、パラメータの最後はAsyncCallbackオブジェクトです。
   
    StockPrice[] getPrices(String[] symbols) → void getPrices(String[] symbols,AsyncCallback<StockPrice[]> callback);
 
  1. クライアントサブパッケージ内で、インターフェイスを作成しStockPriceServiceAsyncと命名します。
  2. スタブコードを以下のコードに置換えます。
    package com.google.gwt.sample.stockwatcher.client;
    
    import com.google.gwt.user.client.rpc.AsyncCallback;
    
    public interface StockPriceServiceAsync {
    
      void getPrices(String[] symbols, AsyncCallback<StockPrice[]> callback);
    
    }
Tip: Eclipse用Googleプラグインは一致する非同期インターフェイスを持たない同期リモートサービスを発見した時、エラーを生成します。自動的に非同期インターフェイスを生成するためにはEclipseでエラー部分で右クリック、クィックフィックスを選択して、”Create asynchronous RemoteService interface”オプションを選びます。

リモートプロシージャコールの作成(※”コールの実行”の方が訳としては正しいかもしれません)

コールバックメソッド

リモートプロシージャを呼び出す時、呼び出し完了時に実行されるコールバックメソッドを指定することが出来ます。サービスプロキシクラスにAsyncCallback オブジェクトを渡すことによってコールバックメソッドを指定します。AsyncCallback オブジェクトは二つのメソッドを含みます。呼び出しが失敗または成功したかどうかによっていずれかが呼ばれます: onFailure(Throwable) and onSuccess(T).
  1. サービスプロキシクラスを作成します。
    StockWatcherクラスでGWT.create(Class)を呼ぶことによってサービスプロキシクラスのインスタンスを作成します.
    private ArrayList stocks = new ArrayList();
      private StockPriceServiceAsync stockPriceSvc = GWT.create(StockPriceService.class);
    エクリプスはGWTに目印を付けます(※赤波下線エラー)
  2. サービスプロキシクラスを初期化し、コールバックオブジェクトのセットアップ、リモートプロシージャへの呼び出しを作成します。
    既存のrefreshWatchListメソッドを以下のコードに置換えます。
    private void refreshWatchList() {
        // Initialize the service proxy.
        if (stockPriceSvc == null) {
          stockPriceSvc = GWT.create(StockPriceService.class);
        }
    
        // Set up the callback object.
        AsyncCallback<StockPrice[]> callback = new AsyncCallback<StockPrice[]>() {
          public void onFailure(Throwable caught) {
            // TODO: Do something with errors.
          }
    
          public void onSuccess(StockPrice[] result) {
            updateTable(result);
          }
        };
    
        // Make the call to the stock price service.
        stockPriceSvc.getPrices(stocks.toArray(new String[0]), callback);
      }
    エクリプスはAsyncCallbackに目印を付けます(※赤波下線エラー)
  3. import宣言を追加します。
    import com.google.gwt.core.client.GWT;
    
    import com.google.gwt.user.client.rpc.AsyncCallback;

リモートプロシージャコールのテスト

この時点で、サービスの作成、モジュールXMLでのその指定、非同期呼び出しを作成する為のメカニズムのセットアップ、サービスを呼び出すためのクライアントサイドでのサービスプロキシの生成が完了しています。 しかしながら問題があります。
  1. Eclipseデバッガを使用して開発モードでStockWatcherを実行します。
  2. 開発シェルウィンドウでエラーログを調べます。
    [ERROR] Type 'com.google.gwt.sample.stockwatcher.client.StockPrice' was not serializable
     and has no concrete serializable subtypes
サービス実装(StockPriceServiceImpl)で、RemoteServiceServletクラスをextendsすることによって,Javaオブジェクトをシリアライズ・デシリアライズするコードを継承します。しかしながら問題はStockPriceクラスがシリアライズ可能であるということを示す為に編集していないことなのです。

 3.Javaオブジェクトのシリアライズ(直列化)

シリアライゼーションはあるアプリケーションから別のアプリケーションへ移動または後で使用する為に貯蔵できるようにするためにするオブジェクトの内容のパッケージング処理です?(※it can be moved?) GWT RPC経由でネットワーク越しにオブジェクトを転送する時は常にオブジェクトはシリアライズされていなければなりません。特にGWT RPCは全てのサービスメソッドパラメータと返される型がシリアライズ可能であることを要求します。
以下の内、一つでもtrueならば、型はシリアライズ可能でサービスインターフェイスで使用することが出来ます:
  • 全てのプリミティブ型 (int, char, boolean, etc.) とそのラッパーオブジェクトはデフォルトでシリアライズ可能です。
  • シリアライズ可能な型の配列は拡張(継承)によってシリアライズ可能です。
  • 以下の三点の要求を満たすクラスはシリアライズ可能です:
    • 直接、またはそれが派生したスーパークラスのいずれかがJava Serializable または GWT IsSerializable インターフェイスのどちらかを実装している?(※becauseがよくわからない)
    • finalでもtransientでもないインスタンスフィールド自身がシリアライズ可能である。(※, and? 何処かの文を流用した名残?)
    • 任意のアクセス修飾子を伴った(引数が0の)デフォルトコンストラクタを持ちます。(例えばprivate Foo(){}は動きます)
GWTはtransientキーワードを尊重します。したがって、このキーワードで指定されたフィールドの値はシリアライズされません。 (したがってRPCコールが使用された時にワイヤー越しに送信されません)
Note: GWTのシリアライズはJavaのSerializableインターフェイスと同じではありません。GWTで何がシリアライズ可能かそうでないかのより詳しい情報については開発者ガイドのSerializable Typesを見てください。

StockPriceのシリアライズ

シリアライゼーションの要求に基づいて、GWT RPCに対する準備をStockPriceクラスにするためには何が必要でしょうか? StockPriceのインスタンスフィールドは全てプリミティブ型なので、この場合、あなたがする必要があることは SerializableまたはIsSeriazableインターフェイスをimplementsすることです。
package com.google.gwt.sample.stockwatcher.client;

import java.io.Serializable;

public class StockPrice implements Serializable {

  private String symbol;
  private double price;
  private double change;

  ...
  1. 開発モードでStockWatcherを更新します。
  2. 株を追加します。
  3. StockWatcher はテーブルに株を追加します;価格とチェンジフィールドはデータを含み、エラーはありません。
    StockWatcherは表面上、全く違いが見えませんが、その下でクライアントサイドで株価を生成する代わりに組み込みサーブレットコンテナ上のサーバサイドのStockPriceServiceサーブレットからその株価の更新を取得します。
この時点で、基本的なRPCメカニズムは動いています。しかしながらTODOが一つ残っています。コールバックが失敗した場合に備えてエラー処理をコード化する必要があります。

 4. 例外の処理

リモートプロシージャの呼び出しに失敗した場合、 原因は2つのカテゴリのうちの一つに分類されます: 予期しない例外(チェックされない例外)またはチェックされる例外。 いずれの場合も例外を処理し、必要に応じてユーザーにフィードバックを供給すべきです。
予期しない例外: 多くの予想外の出来事はリモートプロシージャへの呼び出しの失敗を引き起こすかもしれません: ネットワークはダウンしてるかもしれません; 反対側のHTTPサーバはリスニング(監視)してないかもしれません;DNSサーバは炎上してるかもしれません等等…
GWTがサービスメソッドを呼び出すことが出来る場合、違う型の予期しない例外を起こすことが出来ますが、サービス実装は宣言されていない例外を投げます。例えばバグはNullPointerExceptionを発生させるかもしれません。
サービス実装で予期しない例外が起きた場合、開発モードログのフルスタックトレースを見つけることが出来ます。クライアントサイドでは、onFailure(Throwable) コールバックメソッドが一般的なメッセージを伴ったInvocationExceptionを受け取ります: サーバで呼び出しが失敗した場合は詳細はサーバログを見てください。
チェックされる例外: サービスメソッドがスローするかもしれない特定の例外の型が分かっていて、それをクライアントサイドのコードで処理できるようにしたい場合、チェックされる例外を使用出来ます。必要に応じてサービスインターフェイスメソッドに追加出来るようにGWTはthrowsキーワードをサポートします。RPCサービスメソッドでチェックされる例外が起きた場合、GWTは例外をシリアライズし、処理するためにクライアント上の呼び出し元へ送り返します。

チェックされる例外の作成

RPCでのエラーを処理する方法を学ぶ為に、ユーザーが呼び出しを失敗させる”delisted”とあなたが定義した株コードを追加した場合、エラーを投げます。それからユーザーへエラーメッセージを表示することによって失敗を処理します?  (※delist=証券取引所記載から取り除く保安

例外のチェックとスロー

クラスの作成: DelistedException
  1. delistedの株コードを識別するためのクラスを作成します。
    エクリプスでは、新規Javaクラスウィザードを起動します。 (ファイル(F) > 新規(N) > クラス)
  2. 名前(M)に、DelistedExceptionと入力します。
  3. java.lang.Exception クラスをextend(継承)します。
  4. java.io.Serializable インターフェイスをimplement(実装)します。
    例外はRPCによって送信されるよう設計されています;従ってこのクラスはシリアライズ可能でなければなりません。
  5. 抽象メソッドを継承します。
  6. 完了(F)をクリックします。
    Eclipse はスタブコードのDelistedException クラスを作成します。
  7. スタブコードを以下のコードに置換えます。
    package com.google.gwt.sample.stockwatcher.client;
    
    import java.io.Serializable;
    
    public class DelistedException extends Exception implements Serializable {
    
      private String symbol;
    
      public DelistedException() {
      }
    
      public DelistedException(String symbol) {
        this.symbol = symbol;
      }
    
      public String getSymbol() {
        return this.symbol;
      }
    }
stock price service インターフェイスの更新: StockPriceService
  1. サービスインターフェイスで (StockPriceService)、getPrices(String[]) メソッドへthrows 宣言を付加します。
    StockPriceService.javaで、以下でハイライトされた部分の修正をします。
    package com.google.gwt.sample.stockwatcher.client;
    
    import com.google.gwt.user.client.rpc.RemoteService;
    import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;
    
    @RemoteServiceRelativePath("stockPrices")
    public interface StockPriceService extends RemoteService {
    
      StockPrice[] getPrices(String[] symbols) throws DelistedException;
    }
stock price サービス実装の更新: StockPriceServiceImpl
 サービス実装(StockPriceServiceImpl)へ二つの修正を行う必要があります。.
  1. getPrices(String[]) メソッドへ対応する修正を行います。
    throws 宣言を付加します。
    DelistedException用のimport宣言を追加します。
  2. Delisted Exceptionをスローするためにコードを追加します。
    このサンプルのために、コードはシンプルかつ 株シンボル ERRがウォッチリストへ追加された時に例外をスローするだけにします。
  3. このリストは完成したStockPriceServiceImpl クラスを示します。
    import com.google.gwt.sample.stockwatcher.client.DelistedException;
    
    ...
    
      public StockPrice[] getPrices(String[] symbols) throws DelistedException {
        Random rnd = new Random();
    
        StockPrice[] prices = new StockPrice[symbols.length];
        for (int i=0; i<symbols.length; i++) {
          if (symbols[i].equals("ERR")) {
            throw new DelistedException("ERR");
          }
    
          double price = rnd.nextDouble() * MAX_PRICE;
          double change = price * MAX_PRICE_CHANGE * (rnd.nextDouble() * 2f - 1f);
    
          prices[i] = new StockPrice(symbols[i], price, change);
        }
    
        return prices;
      }
この時点で、例外をスローするコードを作成し終えました。StockPriceServiceAsync.javaでサービスメソッドへthrows宣言を追加する必要はありません。StockPriceServiceAsyncのメソッドは常に直接返ってきます。(非同期であることを思い出してください)  代わりにGWTがonFailure(Throwable) コールバックメソッドを呼び出した時にスローされたどんなチェックされる例外も受け取ります。

エラーメッセージの表示

エラーを表示するために、新しいUIコンポーネントが必要です。最初にどうやってエラーを表示したいかについてちょっと考えてください。すぐにわかる解決策はWindow.alert(String)を使用してポップアップを表示することです。これは株コードを入力している間にユーザーがエラーを受け取る場合には実行出来ます。しかしより現実世界に近いサンプルでは、
ユーザーが監視リストへ株を追加した後にdelistedになった場合、何が発生して欲しいか?または複数のエラーを表示する必要がある場合は?これらの場合、ポップアップアラートは最善のアプローチではありません。
だから株データの取得に失敗した如何なるメッセージも表示するために、Label ウィジェットを実装します。
  1. ユーザーの注意を喚起するようにエラーメッセージ用のスタイルを定義します。
    StockWatcher.cssで、エラーメッセージのクラス属性を備えたどんな要素にでも適用されるスタイルルールを作成します。
    .negativeChange {
      color: red;
    }
    
    .errorMessage {
      color: red;
    }
  2. エラーメッセージのテキストを保持するため、Labelウィジェットを追加します。
    StockWatcher.javaで、次のインスタンスフィールドを追加します。
    private StockPriceServiceAsync stockPriceSvc = GWT.create(StockPriceService.class);
      private Label errorMsgLabel = new Label();
  3. StockWatcher実行時にエラーメッセージラベルの初期化をします。
    onModuleLoad メソッドで、エラーメッセージラベルへセカンダリクラス属性を追加し、StockWatcherのロード時には表示しないようにします。
    stocksFlexTable上のMainパネルへエラーメッセージラベルを追加します。
    // Assemble Add Stock panel.
        addPanel.add(newSymbolTextBox);
        addPanel.add(addButton);
        addPanel.addStyleName("addPanel");
    
        // Assemble Main panel.
        errorMsgLabel.setStyleName("errorMessage");
        errorMsgLabel.setVisible(false);
    
        mainPanel.add(errorMsgLabel);
        mainPanel.add(stocksFlexTable);
        mainPanel.add(addPanel);
        mainPanel.add(lastUpdatedLabel);

エラーの処理

エラーを表示するためのLabelウィジェットを構築したので、エラー処理コードの記述を終了することが出来ます。
更にエラーが修正され場合、あなたはエラーメッセージを隠したいでしょう。(例えば、ユーザーが株テーブルからERRコードを取り除いた場合)
  1. コールバックが失敗した場合に講ずる処置を指定します。
    StockWatcher.javaのrefreshWatchListメソッドで、以下のようにonFailureメソッドを埋めます。
    public void onFailure(Throwable caught) {
            // If the stock code is in the list of delisted codes, display an error message.
            String details = caught.getMessage();
            if (caught instanceof DelistedException) {
              details = "Company '" + ((DelistedException)caught).getSymbol() + "' was delisted";
            }
    
            errorMsgLabel.setText("Error: " + details);
            errorMsgLabel.setVisible(true);
          }
  2. エラーが修正された場合、エラーメッセージウィジェットを隠します。
    updateTable(StockPrice[] prices) メソッドで、エラーをクリアします。
    private void updateTable(StockPrice[] prices) {
        for (int i=0; i < prices.length; i++) {
          updateTable(prices[i]);
        }
    
        // Display timestamp showing last refresh.
        lastUpdatedLabel.setText("Last update : " +
            DateTimeFormat.getMediumDateTimeFormat().format(new Date()));
    
        // Clear any errors.
        errorMsgLabel.setVisible(false);
      }

RPCでの例外処理をテスト

この時点で、例外の作成とチェックをしました—delisted 株コード “ERR”。StockWatcherがdelisted 株コード用の株データを取得するためにリモートプロシージャの呼び出しを作成した場合、呼び出しは失敗し、例外がスローされ、エラーメッセージを表示することによって処理します。
  1. 開発モードでStockWatcherを更新します。
  2. 株コード ERRを追加します。
  3. StockWatcherは赤いエラーメッセージを表示します。有効な株コードデータは更新を停止されます。
    screenshot: RPC error message
  4. 株コード  ERRを削除します。
  5. エラーメッセージが除去されます。有効な株コードデータは更新され続けます。

 次は何?

この時点で、サーバから株データを取得するためのリモートプロシージャの呼び出しを作成しました。
GWT RPCのより詳しい情報については、開発者ガイドのRemote Procedure Callsを見てください。

プロダクションへのサービスへのデプロイ

テストの間中、あなたのRPCサービスのサーバサイドコードをテストするために開発モードに組み込まれているサーブレットコンテナを使用することが出来ます-ちょうどこのチュートリアルでやってきたように。GWTアプリケーションをデプロイする場合、あなたのサービスをホストするためにどんなサーブレットコンテナでも使用できます。web.xml設定ファイルでサーブレットにマップされているURLを使用してクライアントコードがサービスを呼び出せるか確かめてください。
プロダクションサーバへのGWT RPCサーブレットをデプロイする方法を学ぶためには、開発者ガイドのDeploying RPCを見てください

Reference Guide(Blogger Data API)

android用の神経衰弱ゲームを公開しました(・∀・)
The Match-up(Memory) game for android was released!

Google Play:
Mole's Match-up.

Introduction page:
Mole’s Match-upをリリースした∩( ・ω・)∩


http://code.google.com/intl/ja/apis/blogger/docs/2.0/reference.html

 Reference Guide(V2.0)

このドキュメントはBlogger Data API用の未加工のプロトコル(XMLとHTTP)についての詳しい参考文書を提供します。
このドキュメントはプログラミング言語用のクライアントライブラリについての情報を含みません。クライアントライブラリのリファレンス情報についてはデベロッパーズガイドのプログラミング言語固有のセクションからのリンクを見てください。  

 コンテンツ

 対象読者

このドキュメントはBloggerと対話できるJavaクライアントアプリケーションを作成したいプログラマーを対象としています。
リファレンスドキュメントです。
 developer’s guideで表される概念とGoogle Data APIs protocolの背後にある概括的な概念を理解していると仮定します。

 Blogger フィードタイプ

Bloggerはフィード内のブログ内容の2つの表現:完全なフィードとサマリーフィードを提供します。完全なフィードは完全なブログポストを含みます。一方、サマリーフィードは各ポストの短い断片のみを含みます。
ブログの所有者はGUI設定を使用することでそのブログがシンジケータとアグリゲータへ完全なフィードまたはサマリーフィードを提供するかを指定出来ます。
クライアントアプリがフィード用の未承認リクエストを送信した場合、ブログの所有者が指定したどちらのフィードのタイプでも受け取れます。
しかしながら、クライアントアプリが認証済みリクエストを送信した場合はブログの所有者の指定に関わらず、常に完全なフィードを受け取ります。

 ブロガー クエリ パラメータ リファレンス

Blogger データ API は標準Google データ API クエリ パラメータのほとんど全てをサポートします。
Blogger はq(テキスト検索) とauthorパラメータをサポートしません。
orderbyパラメータがupdatedにセットされていない場合、updated-min と updated-max クエリパラメータは無視されます。例えば次のURLは2008/3/16-2008/3/24間に更新されたブログポスト全てを取得します:

http://www.blogger.com/feeds/blogID/posts/default?updated-min=2008-03-16T00:00:00&updated-max;=2008-03-24T23:59:59&orderby;=updated

 Blogger エレメント リファレンス

Blogger データ API は標準Atom エレメント(要素)のみを使います; より詳しい情報についてはAtom 1.0 syndication format specification と Atom Publishing Protocolを見てください。
このセクションの残りはいくつかの標準のエレメントのBloggerでの使用について2,3の具体的な注意を提供します。

Draft エントリ

ドラフト(下書き)ブログエントリは Atom Publishing Protocolドキュメントで定義された拡張要素を使用して印しづけられます。 A draft blog entry is marked using the  extension element defined in the Atom Publishing Protocol document. 以下がdraftエントリの例です:


...

yes

  エレメントが指定されていない場合、そのエントリはドラフトではありません。

 公開日時と更新日時

標準Atomの要素で与えられる時刻はBlogger GUIでユーザーが設定できる”post date”と同等です。
新しいエントリ作成時にクライアントソフトがの値を指定しない場合、Bloggerはエントリのポストデイトに現在のサーバ時間を設定します?(※set~toが今ひとつわからない) クライアントがエントリを編集してもの値を指定しない場合はBloggerはエントリのポストデイトをそのままにします。
しかしながら、クライアントがエントリの作成または編集時に エレメントの値を指定した場合、Bloggerは エントリのポストデイトに指定された値を設定します? これは他のブログシステムからの古いエントリ(オリジナルの作成日時を持ち続けている)をインポートするようなタスクにとって便利です。
Bloggerはエントリが最後に変更された時を指し示すために標準Atomの要素を使います。クライアントはの値をコントロール出来ません; Bloggerは常にクライアントがエントリをポストまたは編集した時のサーバ時間をエントリの最終更新日時に設定します。
  or  の値に基づくエントリをリクエストをするために 標準Google Data APIの published-minpublished-maxupdated-minupdated-max クエリパラメータを使うことが出来ます。しかしながら、更新日時をクエリすることについての注意はBlogger query parameters referenceを見てください。

 ポストへのコメントをリンクする

Blogger export format は一件のAtomフィードドキュメント内にポストとコメントのエントリ両方を含みます。2つのエントリのタイプを区別するために、Bloggerはエレメントを利用します。このエレメントは エントリがポストまたはコメントかどうかを反映するterm パラメータを持ちます。
なお、コメントエントリとそれが属するポストエントリの関連付けはAtom Threading Extensionの使用を通じて遂行されます。以下の例で、コメントエントリ内のrefパラメータ内のポストエントリ識別子を使用することによってポストを示します。さらにhrefパラメータを通じてポストのHTML URLと関連付けています。


xmlns:thr="http://purl.org/syndication/thread/1.0">
...

<-- A blog post entry -->

tag:blogger.com,1999:blog-blogID.post-postID
This is my first post

href="http://blogName.blogspot.com/2007/04/first-post.html">


term="http://schemas.google.com/blogger/2008/kind#post"/>

...


<-- A comment to the blog post entry -->

tag:blogger.com,1999:blog-blogID.post-postID.comment-commentID
This is my first commment

term="http://schemas.google.com/blogger/2008/kind#comment"/>

blogName.blogspot.com/2007/04/first-post.html"
ref="tag:blogger.com,1999:blog-blogID.post-postID"
type="text/html"/>

...


Blogger Feeds Schema Reference

  1. Blogs List Feed
  2. Blog Posts Feed
  3. Blog Comments Feed
  4. Blog Post Comments Feed