フォームクラス以外のサーバーメソッド呼び出し
フォームクラスのsubmit系メソッドはフォームに入力されたデータをサーバーに転送するメソッドで、Formクラスから派生したクラスでのみ使用することができます。PageやField等のForm以外のクラスもサーバーサイドのメソッドを定義して、JavaScriptからそのメソッドを呼び出すことが可能です。
FileUploadFormにはTextFieldを直接配置していましたが、特殊な機能を追加したフィールドを実装するために、TextFieldから派生したText1Fieldクラスを作成します。Text1Field.javaには、フィールドの変更があった際に呼び出されるonChangeメソッドを定義します。
package pagesample.field;
import java.util.Map;
import org.apache.log4j.Logger;
import dataforms.annotation.WebMethod;
import dataforms.controller.JsonResponse;
import dataforms.controller.Response;
import dataforms.field.base.TextField;
/**
* テキストフィールド。
*
*/
public class Text1Field extends TextField {
/**
* コンストラクタ。
*/
public Text1Field() {
super(null);
}
/**
* コンストラクタ。
*/
public Text1Field(final String id) {
super(id);
}
/**
* Logger.
*/
private static Logger logger = Logger.getLogger(Text1Field.class);
/**
* フィールド変更時に呼ばれるサーバーメソッドです。
* @param p パラメータ。
* @return 応答情報。
* @throws Exception 例外。
*/
@WebMethod
public Response onChange(final Map<String, Object> p) throws Exception {
this.methodStartLog(logger, p);
Response ret = new JsonResponse(JsonResponse.SUCCESS, p);
this.methodFinishLog(logger, ret);
return ret;
}
}
このText1Fieldを利用するために、FileUploadForm.javaのTextFieldクラスをText1Fieldに変更します。
/**
* コンストラクタ。
*/
public FileUploadForm() {
super(null);
this.addField(new Text1Field("text1")).setComment("テキスト");
this.addField(new FolderStoreFileField("file1")).addValidator(new RequiredValidator());
}
次に、イベントハンドラを登録するために、以下のText1Field.jsを作成します。Javaソースをコンパイルした後、開発ツールの「Webリソース作成」を使用してText1Field.jsを作成し、その後太字部分を追加してください。
/**
* @fileOverview {@link Text1Field}クラスを記述したファイルです。
*/
/**
* @class Text1Field
*
* @extends TextField
*/
Text1Field = createSubclass("Text1Field", {}, "TextField");
/**
* HTMLエレメントとの対応付けを行います。
*/
Text1Field.prototype.attach = function() {
TextField.prototype.attach.call(this);
var thisField = this;
this.get().change(function() {
thisField.onChange($(this));
});
};
/**
* 変更イベントハンドラ。
* @param {jQuery} f フィールド。
*/
Text1Field.prototype.onChange = function(f) {
var m = this.getAsyncServerMethod("onChange");
m.execute(this.id + "=" + f.val() , function(r) {
logger.log("r=" + JSON.stringify(r));
});
};
Text1Field.jsのattachメソッドではthis.get()メソッドでText1Fieldに対応するjQueryオブジェクトを取得し、それに対して変更イベントのハンドラを登録しています。このイベントハンドラでは、this.getAsyncServerMethod("onChange")でサーバーのonChangeメソッドを取得しています。このメソッドはAsyncServerMethodクラスのオブジェクトを返し、そのクラスのexecuteメソッドを呼び出すことによって、Text1Field.javaで定義したonChangeメソッドを呼び出すことができます。このexecuteメソッドの第一引数はname1=value1&name2=value2のように、application/x-www-form-urlencodedの形式で情報を渡すことができます。今回はtext1=[フィールドに入力された値]という文字列を作成して送信しています。第二引数はサーバーの応答処理メソッドです。
Text1Field.javaのonChangeメソッドはログを出力し、入力されたパラメータをJsonResponseで返すだけの処理です。このページでテキストフィールドを変更すると、サーバーのonChangeが呼び出され以下のサーバーのログが出力されます。
2018-02-28 20:32:42,248 INFO DataFormsServlet - context=/pagesample, uri=/pagesample/pagesample/page/FileUploadPage.df
2018-02-28 20:32:42,251 INFO DataFormsServlet - classname=pagesample.page.FileUploadPage
2018-02-28 20:32:42,251 INFO DataFormsServlet - method=fileUploadForm.text1.onChange
2018-02-28 20:32:42,253 DEBUG Page - csrfToken=F8O8to3LVgzr04iaT+BEOJEqSMJ/oMbnnaDwjq3eTV0IuXUA8pntnQ==
2018-02-28 20:32:42,257 INFO Text1Field - pagesample.field.Text1Field.onChange start param={csrfToken=F8O8to3LVgzr04iaT+BEOJEqSMJ/oMbnnaDwjq3eTV0IuXUA8pntnQ==, text1=テキスト1}
2018-02-28 20:32:42,257 INFO Text1Field - pagesample.field.Text1Field.onChange finish result=dataforms.controller.JsonResponse@c5c651
2018-02-28 20:32:42,258 DEBUG JsonResponse - json={
"contentType": "text/plain; charset=utf-8",
"result": {
"csrfToken": "F8O8to3LVgzr04iaT+BEOJEqSMJ/oMbnnaDwjq3eTV0IuXUA8pntnQ==",
"text1": "テキスト1"
},
"status": 0
}
フィールドクラスはjQuery-uiのAutocompleteや関連データの取得機能等、クライアント、サーバー間の通信が発生する機能をサポートしています。これらの機能はこのAsyncServerMethodクラスを使用して実装しています。
dataforms.jarにはSyncServerMethodという同期通信用のクラスも存在しますが、同期通信はすでに非推奨とされているので、使用はお勧めしません。
最後に
これまでの記事で、クライアント側のJavaScriptクラスとサーバー側のJavaクラス間の通信を説明しました。次回は、各種フィールドクラスの動作とHTMLタグとの関連について解説する予定です。
