GWTでエコーバックを非同期通信でする

ボタンとテキストボックスを配置し、テキストボックスに文字を入力し、ボタンを押す。
サーバに入力文字列を渡し、そのまま返すプログラム。
サーバ間通信は非同期で行う。
というアプリを作成する。

■プロジェクト概要
プロジェクト名:GwtSampleEchoBack
使うソース

    • GreetingService.java
    • GreetingServiceAsync.java
    • GwtSampleEchoBack.java
    • GreetingServiceImpl

■サービスの作成
GreetingService
Stringを受け取り、Stringを返すechobackメソッドを定義する

	public String echoback(String name);

GreetingServiceAsync
GreetingServiceと対になるechobackメソッドを定義する
AsyncはServiceの戻り値をAsyncCallbackのジェネリクスに指定し、戻り値は持たない

	void echoback(String input, AsyncCallback<String> callback);

■GreetingServiceImpl
GreetingServiceを実装したGreetingServiceImplの作成
GreetingServiceImplにechobackメソッドの処理を実装する

	public String echoback(String input) {
		System.out.println("Rec: " + input);
		return input;
	}

ついでに、呼び出し前処理と、呼び出し後処理のメソッドも追加する

	@Override
	protected void onAfterResponseSerialized(String serializedResponse) {
		System.out.println("After: " + serializedResponse);
	}

	@Override
	protected void onBeforeRequestDeserialized(String serializedRequest) {
		System.out.println("Befor: " + serializedRequest);
	}

■GwtSampleEchoBack
クライアント側の作成手順

  • リモートサービスの呼び出しインタフェースを取得
  • Widget初期化
    • sendButton リモートサービスの呼び出し
    • nameField 送信文字
    • results 受信文字
    • serverResponseLabel Error文字
  • ButtonにClickHandlerを実装
  • callbackの作成
  • 呼び出し

リモートサービスの呼び出し用のインターフェースを取得する

private final GreetingServiceAsync greetingService = GWT.create(GreetingService.class);

ClickHandlerを実装とcallback作成

		sendButton.addClickHandler(new ClickHandler(){
			@Override
			public void onClick(ClickEvent event) {
				//callback作成
				AsyncCallback<String> callback = new AsyncCallback<String>(){
					@Override
					public void onFailure(Throwable caught) {
						results.setText("Server Response Error");
						serverResponseLabel.setHTML(caught.getMessage());
					}

					@Override
					public void onSuccess(String result) {
						results.setText(result);
					}
				};
				
				greetingService.echoback(nameField.getText(), callback);
			}
		});//end of addClickHandler

■実行結果

■ソース
■GreetingService.java

package sample.echoback.client;

import com.google.gwt.user.client.rpc.RemoteService;
import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;

/**
 * The client side stub for the RPC service.
 */
@RemoteServiceRelativePath("greet")
public interface GreetingService extends RemoteService {
	/**
	 * クライアントから送信されたメッセージをそのまま返す
	 * @param name クライアントからの送信文字列
	 * @return サーバからの返信文字列
	 */
	public String echoback(String name);
}

■GreetingServiceAsync.java

package sample.echoback.client;

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

/**
 * The async counterpart of <code>GreetingService</code>.
 */
public interface GreetingServiceAsync {
	void echoback(String input, AsyncCallback<String> callback);
}

■GreetingServiceImpl

package sample.echoback.server;

import sample.echoback.client.GreetingService;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;

/**
 * The server side implementation of the RPC service.
 */
@SuppressWarnings("serial")
public class GreetingServiceImpl extends RemoteServiceServlet implements
		GreetingService {

	@Override
	protected void onAfterResponseSerialized(String serializedResponse) {
		System.out.println("After: " + serializedResponse);
	}

	@Override
	protected void onBeforeRequestDeserialized(String serializedRequest) {
		System.out.println("Bfore: " + serializedRequest);
	}

	public String echoback(String input) {
		System.out.println("input:" + input);
		return input;
	}
}
>|java|

■GwtSampleEchoBack.java

package sample.echoback.client;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;

/**
 * Entry point classes define <code>onModuleLoad()</code>.
 */
public class GwtSampleEchoBack implements EntryPoint {

	/**
	 * Create a remote service proxy to talk to the server-side Greeting service.
	 */
	private final GreetingServiceAsync greetingService = GWT
			.create(GreetingService.class);
	
	/**
	 * This is the entry point method.
	 */
	public void onModuleLoad() {
		final Button sendButton = new Button("Send");
		final TextBox nameField = new TextBox();
		final Label results = new Label();
		final HTML serverResponseLabel = new HTML();
		
		nameField.setText("GWT User");
		// We can add style names to widgets
		sendButton.addStyleName("sendButton");
		
		sendButton.addClickHandler(new ClickHandler(){
			@Override
			public void onClick(ClickEvent event) {
				//callback作成
				AsyncCallback<String> callback = new AsyncCallback<String>(){
					@Override
					public void onFailure(Throwable caught) {
						results.setText("Server Response Error");
						serverResponseLabel.setHTML(caught.getMessage());
					}

					@Override
					public void onSuccess(String result) {
						results.setText(result);
					}
				};
				
				greetingService.echoback(nameField.getText(), callback);
			}
		});//end of addClickHandler
		
		//UI
		VerticalPanel panel = new VerticalPanel();
		panel.add(new Label("message: "));
		panel.add(nameField);
		panel.add(sendButton);
		panel.add(new Label("results: "));
		panel.add(results);
		RootPanel.get("panel").add(panel);
		RootPanel.get("error").add(serverResponseLabel);
	}
}

■GwtSampleEchoBack.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- The HTML 4.01 Transitional DOCTYPE declaration-->
<!-- above set at the top of the file will set     -->
<!-- the browser's rendering engine into           -->
<!-- "Quirks Mode". Replacing this declaration     -->
<!-- with a "Standards Mode" doctype is supported, -->
<!-- but may lead to some differences in layout.   -->

<html>
  <head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">

    <!--                                                               -->
    <!-- Consider inlining CSS to reduce the number of requested files -->
    <!--                                                               -->
    <link type="text/css" rel="stylesheet" href="GwtSampleEchoBack.css">

    <!--                                           -->
    <!-- Any title is fine                         -->
    <!--                                           -->
    <title>Web Application Starter Project</title>
    
    <!--                                           -->
    <!-- This script loads your compiled module.   -->
    <!-- If you add any GWT meta tags, they must   -->
    <!-- be added before this line.                -->
    <!--                                           -->
    <script type="text/javascript" language="javascript" src="gwtsampleechoback/gwtsampleechoback.nocache.js"></script>
  </head>

  <!--                                           -->
  <!-- The body can have arbitrary html, or      -->
  <!-- you can leave the body empty if you want  -->
  <!-- to create a completely dynamic UI.        -->
  <!--                                           -->
  <body>

    <!-- OPTIONAL: include this if you want history support -->
    <iframe src="javascript:''" id="__gwt_historyFrame" tabIndex='-1' style="position:absolute;width:0;height:0;border:0"></iframe>

    <h1>Web Application Starter Project</h1>

    <table align="center">
      <tr>
        <td colspan="2" style="font-weight:bold;">GWT Sample EchoBack </td>        
      </tr>
      <tr>
        <td id="error"></td>
      </tr>
      <tr>
        <td id="panel"></td>
      </tr>
    </table>
  </body>
</html>