サーバーサイドのバリデーション
この状態ではバリデーションを実装していないため、IntegerField等に数値以外を入力すると、convertToServerDataで変換エラーが発生してしまいます。serverMethodにサーバーサイドのバリデーションを実装すると以下のようになります。validateメソッドにpを渡すと、フォームに配置された各フィールドのバリデータを呼び出し、入力データのチェックが行われます。validateメソッドで問題が発生した場合、その問題のリストが返されます。このリストの件数が0の場合、convertToServerDataでのデータ変換が保証された状態になっており、変換したデータでサーバー側の処理を行い、その結果をSimpleForm.jsに送信します。リストの件数が1以上の場合、そのリストをSimpleForm.jsに送信します。
/** * サーバーメソッドのサンプル。 * @param p POSTされた情報。 * @return 応答情報。 * @throws Exception 例外。 */ @WebMethod public Response serverMethod(final Map<String, Object> p) throws Exception { this.methodStartLog(logger, p); Response ret = null; //new JsonResponse(JsonResponse.SUCCESS, ""); List<ValidationError> elist = this.validate(p); if (elist.size() > 0) { // バリデーションで問題が発生したので、その情報をSimpleForm.jsに送信。 ret = new JsonResponse(JsonResponse.INVALID, elist); } else { Map<String, Object> data = this.convertToServerData(p); String text1 = (String) data.get("text1"); Integer integer1 = (Integer) data.get("integer1"); BigDecimal numeric1 = (BigDecimal) data.get("numeric1"); java.sql.Date date1 = (java.sql.Date) data.get("date1"); logger.debug("text1=" + text1 + ",integer1=" + integer1 + ",numeric1=" + numeric1 + ",date1=" + date1); // TODO:なんらかの処理を実装 ret = new JsonResponse(JsonResponse.SUCCESS, ""); // 成功時の情報をSimpleForm.jsに送信 } this.methodFinishLog(logger, ret); return ret; }
SimpleForm.javaのserverMethodがバリデーションの結果を返すようになったので、SimpleForm.jsのsendメソッドがバリデーション結果を受信した場合の処理が必要になります。サーバーサイドのバリデーションに対応したSimpleForm.jsのsendメソッドは以下の通りです。
/** * 送信ボタンの処理。 */ SimpleForm.prototype.send = function() { // エラー情報をクリアする。 currentPage.resetErrorStatus(); var thisForm = this; this.submit("serverMethod", function(r) { if (r.status == ServerMethod.INVALID) { // サーバーのバリデーション結果を表示する。 currentPage.setErrorInfo(thisForm.getValidationResult(r), thisForm); } else if (r.status == ServerMethod.SUCCESS) { // TODO:成功時の処理を実装。 logger.log("json=" + JSON.stringify(r)); } }); };
先頭のcurrentPage.resetErrorStatus();はバリデーションの結果表示をクリアするメソッドです。バリデージョンの結果が返った場合、currentPage.setErrorInfo(thisForm.getValidationResult(r), thisForm);でその内容を表示しています。
クライアントサイドのバリデーション
完全なバリデーションはサーバーサイドでないとできません。また、サーバーサイドのバリデーションはセキュリティ面を考慮すると実装が不可欠なものです。しかし、クライアントサイドのバリデーションを実装すると、サーバーとの通信回数を減らすことができ、サーバーや通信回線への負荷を下げることができます。各種フィールドクラスにはサーバーサイドのバリデーションだけでなく、クライアントサイドのバリデーションも組み込まれています。そのためthis.validate()メソッドを呼び出すだけで、クライアントサイドのバリデーションを行うことができます。SimpleForm.jsのsendメソッドを以下のように修正すると、問題のあるデータを入力した場合、サーバーへのアクセス無しにエラーメッセージが表示されます。
/** * 送信ボタンの処理。 */ SimpleForm.prototype.send = function() { // エラー情報をクリアする。 currentPage.resetErrorStatus(); if (this.validate()) { var thisForm = this; this.submit("serverMethod", function(r) { if (r.status == ServerMethod.INVALID) { // サーバーのバリデーション結果を表示する。 currentPage.setErrorInfo(thisForm.getValidationResult(r), thisForm); } else if (r.status == ServerMethod.SUCCESS) { // TODO:成功時の処理を実装。 logger.log("json=" + JSON.stringify(r)); } }); } };
EditFormの保存メソッド等、dataform.jarで用意されているフォームの各メソッドは、このような構造になっています。各種フォームの標準的なメソッドのみで済むシステムの場合、こうした構造を意識する必要はありません。しかし、特殊なボタンを追加し特殊な処理を実装する場合や、dataforms.jarに無いフォームの規定クラスを作成するような場合は、今回の知識が必要になります。
Fromだけでなく、Page、Field等のWebComponentから派生したクラスも、JavaScriptクラスとJavaクラス間の連携をサポートしています。Form以外のクラスは入力情報をまとめてサーバーに送信するsubmitメソッドはサポートされていませんが、SyncServerMethodクラスを使用して、サーバーサイドのメソッドを呼び出すことができるようになっています。次回の記事では、特殊なsubmitメソッドやSyncServerMethodクラスの使い方を解説したいと思います。