前回は、テキストだけを送受信する方法を学びました。
今回は、Javaオブジェクトを送受信します。
■まず、通信のクラスを定義します。いくつかのルールがあります。
①引数のあるコンストラクタがある場合は、デフォルトコンストラクタが必要です。
②シリアライズ(通信するときの直列化という意味)する為、次のインターフェースをつけてねSerializable,IsSerializable
③継承するのはできるだけ避けましょう。できるだけPoJoが望ましい
④プリミティブ型(intなど)やJavaの基本的配列クラス(純粋な配列もクラス.ListやMapなど)は利用できます。
(*)サーバ側のファイルやioを操作するもの、ライブラリは使えないと考えましょう。
⑤自分のクラスを変数で利用する場合は、①~④のルールに沿いましょう。
package kut.hp_rc.shared;
import java.io.Serializable;
import com.google.gwt.user.client.rpc.IsSerializable;
//シリアライズする為、次のインターフェースをつけてねSerializable,IsSerializable
public class PersonClass implements Serializable,IsSerializable{
private static final long serialVersionUID = 1L;
private String name="";
//引数のあるコンストラクタを追加する場合は、デフォルトコンストラクタが必要
public PersonClass(){
}
public PersonClass(String x_name){
name=x_name;
}
public String getName() {
return name;
}
}
次はRPC通信の定義の3点セット
package kut.hp_rc.client;
import kut.hp_rc.shared.PersonClass;
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 {
String greetServer(String name) throws IllegalArgumentException;
//今回はここだけ
PersonClass getPerson(PersonClass client)throws IllegalArgumentException;
}
package kut.hp_rc.client;
import kut.hp_rc.shared.PersonClass;
import com.google.gwt.user.client.rpc.AsyncCallback;
/**
* The async counterpart of <code>GreetingService</code>.
*/
public interface GreetingServiceAsync {
void greetServer(String input, AsyncCallback<String> callback)throws IllegalArgumentException;
//今回はここだけ
void getPerson(PersonClass x_client, AsyncCallback<PersonClass> callback);
}
package kut.hp_rc.server;
import kut.hp_rc.client.GreetingService;
import kut.hp_rc.shared.PersonClass;
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 {
public String greetServer(String input) throws IllegalArgumentException {
//サーバで文字を加工
String p_convert_sv= "Hello, " + input + "!<br><br>I am running ";
return p_convert_sv;
}
/**
* Escape an html string. Escaping data received from the client helps to
* prevent cross-site script vulnerabilities.
*
* @param html the html string to escape
* @return the escaped string
*/
private String escapeHtml(String html) {
if (html == null) {
return null;
}
return html.replaceAll("&", "&").replaceAll("<", "<").replaceAll(
">", ">");
}
//今回はここだけ
@Override
public PersonClass getPerson(PersonClass name) throws IllegalArgumentException {
PersonClass p_person = new PersonClass("サーバで追加=["+name.getName()+"]");
return p_person;
}
}
では、実際の呼び出し側を・・
package kut.hp_rc.client;
import kut.hp_rc.shared.PersonClass;
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.DialogBox;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.Label;
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 Gwt_test implements EntryPoint {
/**
* Create a remote service proxy to talk to the server-side Greeting service.
*/
private final GreetingServiceAsync greetingService = GWT.create(GreetingService.class);
DialogBox dialogBox = new DialogBox();
PersonClass p_person = new PersonClass();
/**
* This is the entry point method.
*/
public void onModuleLoad() {
final TextBox nameField = new TextBox();
nameField.setText("GWT User");
final Label errorLabel = new Label();
final Button closeButton = new Button("Close");
final HTML serverResponseLabel = new HTML();
final Label textToServerLabel = new Label();
//ダイアログ作成の準備
createDialog(closeButton, serverResponseLabel, textToServerLabel);
final Button sendButton = new Button("Send");
//ボタンを押したら、通信を行う。
sendButton.addClickHandler(new ClickHandler(){
@Override
public void onClick(ClickEvent event) {
String p_send_txt=nameField.getText();
//今回はここだけ
PersonClass p_person= new PersonClass(p_send_txt);
greetingService.getPerson(p_person, new AsyncCallback<PersonClass>() {
@Override
public void onFailure(Throwable caught) {
// TODO 自動生成されたメソッド・スタブ
}
@Override
public void onSuccess(PersonClass result) {
dialogBox.setText("Remote Procedure Call");
serverResponseLabel.setHTML(result.getName());
dialogBox.center();
closeButton.setFocus(true);
}});
}});
// Add the nameField and sendButton to the RootPanel
// Use RootPanel.get() to get the entire body element
RootPanel.get("nameFieldContainer").add(nameField);
RootPanel.get("sendButtonContainer").add(sendButton);
RootPanel.get("errorLabelContainer").add(errorLabel);
// Add a handler to close the DialogBox
closeButton.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
dialogBox.hide();
sendButton.setEnabled(true);
sendButton.setFocus(true);
}
});
sendButton.addStyleName("sendButton");
}
/**
* @param closeButton
* @param serverResponseLabel
* @param textToServerLabel
*/
public void createDialog(final Button closeButton, final HTML serverResponseLabel, final Label textToServerLabel) {
// Create the popup dialog box
VerticalPanel dialogVPanel = new VerticalPanel();
dialogBox.setText("Remote Procedure Call");
dialogBox.setAnimationEnabled(true);
// We can set the id of a widget by accessing its Element
dialogVPanel.addStyleName("dialogVPanel");
dialogVPanel.add(new HTML("<b>Sending name to the server:</b>"));
dialogVPanel.add(textToServerLabel);
dialogVPanel.add(new HTML("<br><b>Server replies:</b>"));
dialogVPanel.add(serverResponseLabel);
dialogVPanel.setHorizontalAlignment(VerticalPanel.ALIGN_RIGHT);
dialogVPanel.add(closeButton);
closeButton.getElement().setId("closeButton");
dialogBox.setWidget(dialogVPanel);
}
}
動作としては、
フロント側でPersonクラスを作成して、テキストボックスの値を名前として設定
通信3点セットで作ったgetPersonメソッドで、サーバ側にオブジェクトを渡して
サーバ側で、名前を変更して、フロント側に返して
フロント側では、オブジェクトを取り出して、変更された名前を表示させています。