GWTのRequestFactoryを使う
サーバーサイドのEntityをクライアントで使えるように出来るらしいのでやってみる。
S2JDBCのEntityを利用した。
http://code.google.com/intl/ja/webtoolkit/doc/latest/DevGuideRequestFactory.html
ここの通りにファイルを作っていく。
テーブルはidとtextだけの単純なものを使った。
db=> \d category Table "public.category" Column | Type | Modifiers -------------+---------+----------- category_id | integer | not null category | text | not null version | integer | not null Indexes: "category_pkey" PRIMARY KEY, btree (category_id) "category_category_key" UNIQUE, btree (category) db=> insert into category values(1, 'テスト', 1);
まずプロキシやリクエストクラスを作る。
app/client/shared/CategoryProxy.java
@ProxyFor(Category.class) public interface CategoryProxy extends EntityProxy { Long getId(); String getCategory(); void setCategory(String category); }
app/client/shared/CategoryRequest.java
@Service(Category.class) public interface CategoryRequest extends RequestContext { Request<CategoryProxy> findCategory(Long id); InstanceRequest<CategoryProxy, Void> insert(); }
アノテーションでエラーが出るがここでは気にせずに先に進む。
app/client/shared/AppRequestFactory
public interface AppRequestFactory extends RequestFactory { CategoryRequest categoryRequest(); }
取得と更新。
// onModuleLoadの中 AppRequestFactory requestFactory = GWT.create(AppRequestFactory.clas s); requestFactory.initialize(eventBus); CategoryRequest request = requestFactory.categoryRequest(); request.findCategory((long)1).fire(new Receiver<CategoryProxy>(){ @Override public void onSuccess(CategoryProxy response) { Window.alert(response.getId() + ":" + response.getCategory()); } }); request = requestFactory.categoryRequest(); CategoryProxy newCategory = request.create(CategoryProxy.class); newCategory.setCategory("日本語"); Request<Void> insertReq = request.insert().using(newCategory); insertReq.fire(new Receiver<Void>(){ @Override public void onSuccess(Void response) { } });
対応するEntityのメソッドを作る。
app/server/entity/Category.java
public class Category implements Serializable { private static final long serialVersionUID = 1L; /** categoryIdプロパティ */ @Id @Column(precision = 10, nullable = false, unique = true) public Integer categoryId; /** categoryプロパティ */ @Lob @Column(length = 2147483647, nullable = false, unique = true) public String category; @Version public Integer version = 0; public static Category findCategory(Long id){ Category c = SingletonS2Container.getComponent(CategoryService.class) .findById(id.intValue()); return c; } public void insert(){ // データが来ているか確認だけする System.out.println(this.category); } public Long getId(){ if (categoryId == null) return null; return categoryId.longValue(); } public Integer getVersion(){ return version; } public String getCategory(){ System.out.println(category); return category; } public void setCategory(String c){ category = c; } }
S2JDBCのEntityを使うと不格好になった。この書き方だとS2Daoを使うべき?
インターフェースを使っているわけではないが、CategoryRequestのメソッド定義と合わせる必要がある。その他必須メソッドもいくつかある。
メソッドの不一致とかがあればログに出ているのでメッセージの通りに修正すれば大抵直ると思う。
これでJavaのソースは完了。
実行のために必要なjarを適当に取ってくる。
json-20090211.jar validation-api-1.0.0.GA.jar hibernate-validator-4.0.2.GA.jar slf4j-log4j12-1.6.1.jar slf4j-api-1.6.1.jar をパスに追加。
今回は手動でDLして追加した。
<inherits name="com.google.gwt.requestfactory.RequestFactory"/>
これを追加する。
web.xmlの編集。
<servlet> <servlet-name>requestFactoryServlet</servlet-name> <servlet-class>com.google.gwt.requestfactory.server.RequestFactoryServlet</servlet-class> <load-on-startup>2</load-on-startup> </servlet> <servlet-mapping> <servlet-name>requestFactoryServlet</servlet-name> <url-pattern>/gwtRequest</url-pattern> </servlet-mapping>
リクエストを受け取る/gwtRequestは固定らしい。ソースのTODOに書いてあった。
このサーブレットはseasar管理外なので、ちゃんとやるならプロキシを挟んだ方がいい。
で、いざ実行!してみると、日本語が出ない…。
サーバー側には日本語が渡ってきているので、レスポンスJSONの文字コードがダメっぽい。これはどうすればいいんだろう。
sharedのアノテーションでエラーが出ているが、実行は出来る。
GWTプラグインの問題らしい。
http://code.google.com/p/google-web-toolkit/issues/detail?id=5587
この辺に書いてある。
うーん。
使えるか使えないか微妙のまま一端終了。
S2JDBCとは合わない感じ。Entity Bean専用なのかな。
まだ見送った方がいいのかもわからんね。