slim3gwtを試す

昨日の猫Managerの一部をGWTで動かしてみました。まだslim3がGWTに対応していないころにやってできなかったことがあまりにも簡単にできてしまいました。メモしておきます。


まずEclipseGWTとGAE対応の新規プロジェクトを作ったら、slim3gwt-demoプロジェクトから自分のプロジェクトに必要そうなものをコピーしました。


別にdemoを使わせてもらってそのままやれば簡単にできそうですが、一応こんな感じでやってます。プロジェクト名はcat-slim3-gwtです。


HTMLファイルは動的なコンテナ部分は自分で書き換えます。一番下のtableタグの部分を今回はこんな感じにしてます。

<table align="center">
	<tr>
		<td colspan="2" style="font-weight: bold;">Please enter your name:</td>
	</tr>
	<tr>
		<td id="nameFieldContainer"></td>
		<td id="searchButtonContainer"></td>
		<td id="insertButtonContainer"></td>
	</tr>
</table>


web.xmlは基本的には全コピーして、rootPackageとは変更しました。

次に、WEB-INF/libにslim3-EA1-SNAPSHOT.jarをコピーします。

次にslim3gwt-demoのビルドパスと同じようにビルドパスを設定します。

次に前回ミスってたAnnotation Processing Factoryへjarファイルを登録します。

jdoconfig.xmlも丸ごとコピーしました。

EclipseでGWTGAEプロジェクト作成時自動で生成されるGreetService的なものはいらないので削除しました。


こうしてbuld.xmlでslim3genを動かすと、ServiceとServiceAsyncとサーバ側ServiceImplを自動で生成してくれます。generateしてみます。


ポップアップウインドウが表示されたらCatServiceと入力することで自動でCatService,CatServiceAsync,CatServiceImplが生成されます。


この状態ではroot.client配下のonModuleLoad()のあるブートクラスがコンパイルエラーになるので、GreetingServiceAsyncで宣言されているserviceを自身で作成したものに変更します。コンパイルエラーが消えます。


こんな感じに変えます。
Cat_slim3_gwt.java

private final CatServiceAsync greetingService = GWT.create(CatService.class);


modelもgen-modelで昨日と同じKindとCatを作成しました。
こちらにも書いてあるとおり、クライアントとサーバ両方でmodelは共用できるとのこと。


単にKindの登録と全検索を実装したのが以下です。
あくまでためしなのでコンソールに結果をprintしているだけの実装ですが、insertと検索はあっというまにできました。


Cat_slim3_gwt.java

public class Cat_slim3_gwt implements EntryPoint {

	private final CatServiceAsync catService = GWT.create(CatService.class);

	public void onModuleLoad() {
		final Button kindInsertButton = new Button("登録");
		final Button kindSearchButton = new Button("全検索");
		final TextBox nameField = new TextBox();
		nameField.setText("ねこの種類を入力してね!");

		kindInsertButton.addStyleName("sendButton");
		kindSearchButton.addStyleName("sendButton");

		RootPanel.get("nameFieldContainer").add(nameField);
		RootPanel.get("insertButtonContainer").add(kindInsertButton);
		RootPanel.get("searchButtonContainer").add(kindSearchButton);

		nameField.setFocus(true);
		nameField.selectAll();

		class InsertKindHandler implements ClickHandler {

			public void onClick(ClickEvent event) {
				sendNameToServer();
			}

			private void sendNameToServer() {
				kindInsertButton.setEnabled(false);
				String textToServer = nameField.getText();
				Kind kind = new Kind();
				kind.setName(textToServer);
				catService.insertKind(kind, new AsyncCallback<Kind>() {
					public void onFailure(Throwable caught) {
					}

					public void onSuccess(Kind result) {
						System.out.println(result.getName());
						kindInsertButton.setEnabled(true);
					}
				});
			}
		}

		class SearchKindHandler implements ClickHandler {

			public void onClick(ClickEvent event) {
				searchAllKind();
			}

			private void searchAllKind() {
				kindSearchButton.setEnabled(false);
				catService.searchAll(new AsyncCallback<List<Kind>>() {
					public void onFailure(Throwable caught) {
					}
					public void onSuccess(List<Kind> result) {
						for (Kind kind : result) {
							System.out.println(kind.getName());
						}
						kindSearchButton.setEnabled(true);
					}
				});
			}
		}
		InsertKindHandler handler = new InsertKindHandler();
		SearchKindHandler shanHandler = new SearchKindHandler();
		kindInsertButton.addClickHandler(handler);
		kindSearchButton.addClickHandler(shanHandler);

	}
}


CatService.java

@RemoteServiceRelativePath("service.s3gwt")
public interface CatService extends RemoteService {
	Kind insertKind(Kind kind);
	List<Kind> searchAll();
}


CatServiceAsync.java

package kijitoraneko.demo.client.service;

import java.util.List;

import kijitoraneko.demo.shared.model.Kind;

import com.google.gwt.user.client.rpc.AsyncCallback;

public interface CatServiceAsync {

	void insertKind(Kind kind, AsyncCallback<Kind> callback);

	void searchAll(AsyncCallback<List<Kind>> callback);

}


CatServiceImpl.java

package kijitoraneko.demo.server.service;

import java.util.List;

import kijitoraneko.demo.client.service.CatService;
import kijitoraneko.demo.server.dao.KindDao;
import kijitoraneko.demo.shared.model.Kind;

public class CatServiceImpl implements CatService {

	KindDao dao = new KindDao();

	@Override
	public Kind insertKind(Kind kind) {
		return dao.makePersistentInTx(kind);
	}

	@Override
	public List<Kind> searchAll() {
		return dao.findAll();
	}
}


Kind.java

@PersistenceCapable(identityType = IdentityType.APPLICATION)
@Version(strategy = VersionStrategy.VERSION_NUMBER, column = "version")
public class Kind implements Serializable {

    private static final long serialVersionUID = 1L;

    @PrimaryKey
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
    @Extension(vendorName = "datanucleus", key = "gae.encoded-pk", value = "true")
    private String key;

    @Persistent
    private Long version = 1L;

    @Persistent
    private String name;

    /**
     * Returns the key.
     *
     * @return the key
     */
    public String getKey() {
        return key;
    }

    /**
     * Sets the key.
     *
     * @param key
     *            the key
     */
    public void setKey(String key) {
        this.key = key;
    }

    /**
     * Returns the version.
     *
     * @return the version
     */
    public Long getVersion() {
        return version;
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}


modelは、detachableの設定をはずしてください。 とのことですのでそのようにします。


Cat_slim3_gwt.gwt.xmlもdemoのプロジェクトを参考に変更します。

<inherits name='org.slim3.gwt.emul.S3Emulation'/>

<source path="client"/>
<source path="shared"/>

を追加。


単純な登録と検索はこれでOKです。メモでした。