APIの作成
では、これらのAPIを作成していこう。APIを用いるアプリケーションは、前回と同様の英単語テストアプリケーションだ(図1)。
a. Serviceインタフェース
まず、処理のためのメソッドをServiceインタフェースとして作成する。ここでは、日本語と英単語とが一対になった単語帳データを出題用に1件ずつ受信するメソッドと、単語帳データの件数を取得するメソッドの2つをリスト1のように作成する。
リスト1 Serviceインタフェース(Java)
package gwt.example.client;
import com.google.gwt.user.client.rpc.RemoteService;
public interface QuestionService extends RemoteService {
// 単語帳データを1件ずつ取得するメソッド
Question getQuestion( String genre, int idx );
// 単語帳データの件数を取得するメソッド
int getQuestionCount( String genre );
}
b. ServiceAsyncインタフェース
ServiceAsyncインタフェースは、アプリケーション実行時にGWTによって生成するプロキシクラスのために用意するものだ。これにはServiceインタフェースに対応したメソッドが実装されるが、リスト2に示すように以下の4点が異なる。
- 継承なし
- インタフェース名は"Serviceインタフェース名 + Async"
- メソッドの戻り値はvoid
- 引数の最後にAsyncCallbackを追加
リスト2 ServiceAsyncインタフェース(Java)
package gwt.example.client;
import com.google.gwt.user.client.rpc.AsyncCallback;
public interface QuestionServiceAsync {
void getQuestion( String genre, int idx, AsyncCallback callback );
void getQuestionCount( String genre, AsyncCallback callback );
}
c. Serviceインタフェースを実装したサーブレット
サーブレットとは、サーバ側で実行されるプログラムのことをいう。GWTのサーブレットは、リスト1のインタフェースを実装し、且つRemoteServiceServletを継承しなくてはならない。
実装されたメソッドは、クライアントのプロキシクラスからの指示により実行され、メソッドの戻り値はクライアントに提供されるデータ(単語帳データ1件分など)となる。
リスト1、リスト2とは異なるserverパッケージに配置することに注意が必要だ。
リスト3 アプリケーションにデータを提供するサーブレット(Java、UTF-8で記述)
package gwt.example.server;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import java.util.HashMap;
import gwt.example.client.Question;
import gwt.example.client.QuestionService;
public class QuestionServiceImpl extends RemoteServiceServlet
implements QuestionService {
private final HashMap questions = new HashMap();
private final String genre = "fruits";
public QuestionServiceImpl() {
initQuestion();
}
// 単語帳データを1件ずつ取得するメソッド
public Question getQuestion( String genre, int idx ) {
String[][] question = (String[][])questions.get( genre );
return new Question( question[ idx ][ 0 ],
question[ idx ][ 1 ] );
}
// 単語帳データの件数を取得するメソッド
public int getQuestionCount( String genre ) {
return ((String[][])questions.get( genre )).length;
}
// 単語帳データの初期化
private void initQuestion() {
String[][] question = new String[][] {
{ "りんご" , "apple" },
{ "みかん" , "orange" },
{ "もも" , "peach" },
{ "いちご" , "strawberry" },
{ "パパイヤ", "papaya" }
};
questions.put( genre, question );
}
}
d. クライアントに提供されるデータを収めるクラス
サーバからクライアントに提供するデータを収めるクラスをリスト4に示す。内容は一般的なPOJOであるが、IsSerializableの実装によりシリアライズ可能になっている。これによってデータ通信に用いられるオブジェクトだとわかるのだ。
必ず引数なしのコンストラクタが必要なので、注意していただきたい。
リスト4 データを収めるクラス(Java)
package gwt.example.client;
import com.google.gwt.user.client.rpc.IsSerializable;
public class Question implements IsSerializable {
String text, answer; // 日本語, 英単語
public Question() {} // 引数なしのコンストラクタを必ず宣言する
public Question( String text, String answer ) {
setText( text );
setAnswer( answer );
}
public String getText() { return text; }
public String getAnswer() { return answer; }
public void setText ( String text ) { this.text = text; }
public void setAnswer( String answer ) { this.answer = answer; }
}