SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

特集記事

dataforms.jar API解説――ファイルのアップロード・ダウンロードの実装

フォームクラス以外のサーバーメソッド呼び出し

 フォームクラスのsubmit系メソッドはフォームに入力されたデータをサーバーに転送するメソッドで、Formクラスから派生したクラスでのみ使用することができます。PageやField等のForm以外のクラスもサーバーサイドのメソッドを定義して、JavaScriptからそのメソッドを呼び出すことが可能です。

 FileUploadFormにはTextFieldを直接配置していましたが、特殊な機能を追加したフィールドを実装するために、TextFieldから派生したText1Fieldクラスを作成します。Text1Field.javaには、フィールドの変更があった際に呼び出されるonChangeメソッドを定義します。

Text1Field.java
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に変更します。

FileUploadForm.java
  /**
   * コンストラクタ。
   */
  public FileUploadForm() {
    super(null);
    this.addField(new Text1Field("text1")).setComment("テキスト");
    this.addField(new FolderStoreFileField("file1")).addValidator(new RequiredValidator());
  }
    

 次に、イベントハンドラを登録するために、以下のText1Field.jsを作成します。Javaソースをコンパイルした後、開発ツールの「Webリソース作成」を使用してText1Field.jsを作成し、その後太字部分を追加してください。

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が呼び出され以下のサーバーのログが出力されます。

text1の変更時のサーバーログ
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タグとの関連について解説する予定です。

この記事は参考になりましたか?

連載通知を行うには会員登録(無料)が必要です。
既に会員の方はを行ってください。
特集記事連載記事一覧

もっと読む

この記事の著者

高柳 正彦(タカヤナギ マサヒコ)

経験年数30年を超えた、システムエンジニアです。一応管理職のはずですが、未だにコードを書いています。この仕事を長々とやっていると、それなりにノウハウがたまってきます。そのノウハウをまとめたものができないかと思い、独自のフレームワークを作り始めました。そのフレームワークもそれなりに使えるようになってき...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/10708 2018/04/16 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー