フロントとサーバの通信方法(RPC)　Javaオブジェクトを送受

前回は、テキストだけを送受信する方法を学びました。
今回は、Javaオブジェクトを送受信します。

今回のファイルの場所です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132663/1c7648b9-d21b-cc88-1136-8cf24e072e09.png)


■まず、通信のクラスを定義します。いくつかのルールがあります。	

①引数のあるコンストラクタがある場合は、デフォルトコンストラクタが必要です。	
②シリアライズ(通信するときの直列化という意味)する為、次のインターフェースをつけてねSerializable,IsSerializable	
③継承するのはできるだけ避けましょう。できるだけPoJoが望ましい	
④プリミティブ型(intなど）やJavaの基本的配列クラス(純粋な配列もクラス.ListやMapなど）は利用できます。	
	（＊）サーバ側のファイルやioを操作するもの、ライブラリは使えないと考えましょう。
⑤自分のクラスを変数で利用する場合は、①～④のルールに沿いましょう。	


```PersonClass.java
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通信の定義の３点セット
```GreetingService.java
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;
}

```

```GreetingServiceAsync.java
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);
}

```

```GreetingServiceImpl.java
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("&", "&amp;").replaceAll("<", "&lt;").replaceAll(
				">", "&gt;");
	}

    //今回はここだけ
	@Override
	public PersonClass getPerson(PersonClass name) throws IllegalArgumentException {

		PersonClass p_person = new PersonClass("サーバで追加=["+name.getName()+"]");
		return p_person;
	}
}

```

では、実際の呼び出し側を・・

```Gwt_test.java
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クラスを作成して、テキストボックスの値を名前として設定
通信３点セットで作ったgetPersonメソッドで、サーバ側にオブジェクトを渡して
サーバ側で、名前を変更して、フロント側に返して
フロント側では、オブジェクトを取り出して、変更された名前を表示させています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132663/dbf69c83-2519-25a4-5879-a89cba7c8e20.png)