はじめに

こんにちは。テクノロジー&エンジニアリングセンターの羽部です。

今回は、Nablarch解説書に記載されているけれど、埋もれてしまって探しにくい情報を掘り起こして説明するのを目的に記事を書きました。

Nablarchで例外発生時の処理を書くとしたら、@onErrorを使い、path属性に例外発生時の遷移先を指定します。多くはJSPを指定するでしょう。

しかし、入力値のバリデーションでエラーになって入力画面のJSPに戻したらプルダウンリストが消えちゃった、という経験はありませんか。消える理由は思い当たるけれど対応策がわからなかったり、取った対応策が果たして適切なのか悩んだりといった場合もあるでしょう。

本記事では、なぜプルダウンリストが消えるのか、そしてそれを回避するにはどうすればよいのかを紹介します。

なお、Nablarchはバリデーション(入力値のチェック)を行う方法として、以下の2種類の機能を提供しています。

本記事では、Nablarchが推奨するBean Validationを対象とします。

バリデーションでエラーが発生した場合のselectタグなどの選択肢の表示

プルダウンリストが消えてしまう理由

入力値のバリデーションでエラーになって入力画面のJSPに戻したら、プルダウンリストが消えてしまう。これは、カスタムタグのselectタグやcheckboxesタグなど、リクエストスコープに格納されている情報を元に選択肢を表示するタグ全般に言えることです。バリデーションでエラーが発生した場合、以下のような実装で単純にJSPに遷移させるとプルダウンリストやチェックボックスが表示されません。

@OnError(type = ApplicationException.class, path = "input.jsp")

なぜでしょうか。

それは、入力画面(この例ではinput.jsp)を表示するリクエストと、バリデーションを行うリクエストが異なるからです。

入力画面を表示するリクエストでは、リクエストスコープに選択肢の情報を格納します。JSPではその情報を利用して、プルダウンリストなどを表示しています。格納先はリクエストスコープですから、JSPを表示してしまえば選択肢の情報はなくなってしまいます。このため、バリデーションを行うリクエストの際には、選択肢の情報はどこにもありません。表示すべき情報がない場合、selectタグなどは何も表示しない仕様になっているため、プルダウンリストが消える、という現象が発生します。

対応策

このような場合の対応策は、単純にJSPに遷移させるのではなく、選択肢の情報をリクエストスコープに格納するメソッドへフォワードさせることです。

具体例を示しましょう。

/**
 * バリデーションエラー時に呼び出されるメソッド
 */
public HttpResponse view(HttpRequest request, ExecutionContext context) {

    /*
     * 選択肢を作成し、リクエストスコープに格納する処理を記述する。
     */

    // 入力画面は"input.jsp"だとする。
    return new HttpResponse("input.jsp");
}

/**
 * バリデーションを実行するメソッド。
 * サブミットボタンの押下などによって呼び出される。
 * バリデーションエラー(ApplicationException)発生時は、viewメソッドにフォワードする。
 */
@InjectForm(form = Sample.class)
@OnError(type = ApplicationException.class, path = "forward://view")
public HttpResponse confirm(HttpRequest request, ExecutionContext context) {

    // ~略~

    return new HttpResponse("confirm.jsp");
}

ポイントは、@onErrorpathの値がforward://~となっているところです。の部分に呼び出したいメソッド名(この例ではview)を記述します。

この例では、選択肢を作成しリクエストスコープに格納する処理を行うメソッドを1つ作成しましたが、初期表示のメソッドがそのまま使えるならば別途用意する必要はありません。 初期表示のメソッドがそのまま使えるかの判断基準は、ユーザの入力値を保存できるか否かです。

例えば、新規登録機能で入力欄の初期値がない画面の場合。初期表示メソッドはselectタグなどの選択肢を用意する処理が主で、画面の入力欄に値を設定するような処理は行っていないでしょう。 この場合、バリデーションエラー発生後に初期表示メソッドを呼び出しても、ユーザの入力値は保存され(そのまま画面に表示され)ます。選択肢を準備するメソッドとして、初期表示メソッドを使いまわすことができます。

一方、更新機能の場合、初期表示メソッドではDBに格納されている値を入力画面に表示する処理を行っているでしょう。この場合、バリデーションエラー発生後に初期表示メソッドを呼び出すと、ユーザの入力値ではなく、初期値が入力画面に表示されてしまいます。ですから、初期表示メソッドとは別に、選択肢を準備するメソッドが必要になります。

おわりに

いかがだったでしょうか。プルダウンリストやチェックボックスが消える原因は思いついても、対応策にたどり着くのが少し難しいところです。この記事が、そんな時のお役に立てれば幸いです。


本コンテンツはクリエイティブコモンズ(Creative Commons) 4.0 の「表示—継承」に準拠しています。