Struts2-GWTインテグレーション

GWTの単体での使い方、GWTでのRPC(AJAX)発行は問題無いことがわかった。

で、フレームワークへのGWTの取り込み方法として、次の方式とする。

基本的にはクライアント側では既存のフォーム要素とGWTの要素は関連性を持たせず、GWTGWTの世界でフレームワークのActionをRPCで呼び出し、クライアントの操作に応答する。

Struts2の既存フォーム要素との連携はGWTからJSNI(JavascriptNativeInterface)にて設定/取得を行う。

まずは、GWTのRPCをStruts2のアクションで受ける為の準備から。

Google Code Archive - Long-term storage for Google Code Project Hosting.の struts2gwtplugin-0.2.1-bin.zip を落としてきて、中に入っている struts2gwtplugin-0.2.1.jar を取り出して、 WEB-INF/lib に入れる。解説は http://cwiki.apache.org/S2PLUGINS/gwt-plugin.html を参照。

拍子抜けしそうだけど、これだけでOK。

あとは、まえにGWT用に作ったRPCサービスをStruts2用のアクションに書き換える。
純粋なStruts2のアクションの形ではなく、GWTのRPCサービスと全く同じメソッドを用意してあげ、"success"とかの戻り値は返さない。

RemoteServletServiceを親クラスにする必要は無い。

package tutorial.gwt.server;

import tutorial.gwt.client.MyService;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;

@Struts2Action("MyServiceImpl")
@Scope("request")
public class MyServiceImpl implements MyService {
	public Integer countUp(Integer cnt) {
		System.out.println("Cnt:"+cnt);
		return cnt+1;
	}

	public Integer reset() {
		System.out.println("Reset");
		return 0;
	}
}

プラグインがRPCの呼び出しからメソッドへのマッピングを行ってくれるので、RPCの呼び出しメソッドが正しく呼ばれる。
生成はSpringでやっているので、好きなだけ@ResourceでDIもできる。

struts.xmlでは次のようにアクションを定義、メソッド名の指定が無いのがポイント。

  <package name="example"  extends="gwt-default">
        <default-interceptor-ref name="gwt"/>

        <action name="MyService" class="MyServiceImpl" />
  </package>

あと、web.xmlにCypalが追加した、サーブレットが登録されているので、次の記述を削除する。

<servlet>
	<servlet-name>MyService</servlet-name>
	<servlet-class>
	tutorial.gwt.server.MyServiceImpl</servlet-class>
</servlet>
<servlet-mapping>
	<servlet-name>MyService</servlet-name>
	<url-pattern>/MyService.action</url-pattern>
</servlet-mapping>

Springでのtutorial下をスキャンする設定にしていない場合はスキャンする設定にする。
applicationContext.xml

<context:component-scan base-package="tutorial">
  <context:include-filter type="annotation" expression="jp.co.hershe.struts2.util.Struts2Action"/>
</context:component-scan>