GWTでサーバサイドロジックを呼び出すためには、用意されているRPC(Remote Procedure Call)の仕組みを利用する。
一方、近年のJavaによるWebアプリケーション開発では、ビジネスロジックのインスタンス管理は、何らかのDIコンテナに任せてしまうのが常套手段だ。個人的には長いことSpringを使っていることもあり、GWTのRPCをSpringのbeanに置き換えできないかを試してみることにした。
使用したのは下記のライブラリ。
GWT Server Library (GWT-SL)
http://gwt-widget.sourceforge.net/
GWTのRPCは特定のurlにマッピングされたServletとして動作するが、GWT-SLではurlとSpringのbeanをマッピングするモジュールを用意されており、それとSpringMVCのDispatcherServletと組み合わせてSpringのbeanを呼び出せるようになっている。
GWT-SLでRPCとして公開可能なbeanには、下記の3種類の戦略が用意されている。
- 完全なるPOJO
- GWT RPCのServiceインタフェースを実装したクラス
- GWT RPCのServiceインタフェースを実装し、GWTSpringControllerを継承したクラス
POJOは公開されるRPCのインタフェースに関連がないクラスになるため、メソッドが増えると管理が難しそう。3番目の方法は古いバージョンのGWT-SLにおける手法(ただしパフォーマンスはよいとのこと)らしいので、2番目の方法を前提とした構築手順を下記に示す。
1. GWT-SLをダウンロードし、WEB-INF/lib配下に置く。
2. GWT-SLのServletを定義する。
下記の記述をweb.xmlに追記する。
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet><servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>*.rpc</url-pattern>
</servlet-mapping>
※servlet-nameやurl-patternは特に限定されておらず、任意の値で設定できる。
3. Springの定義ファイルにマッピング情報を記述する。
Springの定義ファイルは、web.xmlで記述したServlet名によって変わり、WEB-INF/[サーブレット名]-servlet.xmlとなる。
<bean id="urlMapping" class="org.gwtwidgets.server.spring.GWTHandler">
<property name="mapping">
<map>
<entry key="/test.rpc" value-ref="testServiceImpl" />
</map>
</property>
</bean>
いちいちbean名とurlの記述を書かなければならないのがめんどくさいと思ったが、よくよく考えたら何でもかんでもRPCとして公開されたら大変なのでこれは仕方のないことだ。
4. GWTモジュールから呼び出す。
TestServiceAsync service = GWT.create(TestService.class);
ServiceDefTarget target = ((ServiceDefTarget) service);
target.setServiceEntryPoint(GWT.getModuleBaseURL() + "test.rpc");
service.hoge();
これでSpringのbean呼び出しが可能である。
ただこのままでは、GWTのhostedモードでRPCの呼び出しができない。モジュールをリコンパイルしてデプロイし直すのでは恐ろしく時間がかかりすぎるため、次回はhostedモードでSpring RPCを呼び出す方法を書く。