ログ日記

作業ログと日記とメモ

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して追加した。


gwt.xmlの編集。

    <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専用なのかな。


まだ見送った方がいいのかもわからんね。