[Subsonic Airlines] 会員登録画面 – バッキングビーンの作成5

バッキングビーンの説明の第5回です。

これまでの記事
設定ファイルの作成
http://subsonic.info/ja/2015/08/23/subsonic-airlines-会員登録画面-設定ファイルの作成/

テンプレートの作成
http://subsonic.info/ja/2015/08/27/subsonic-airlines-会員登録画面-テンプレートの作成/

トップ画面の作成
http://subsonic.info/ja/2015/08/28/subsonic-airlines-会員登録画面-トップ画面の作成/

入力画面の作成
http://subsonic.info/ja/2015/08/31/subsonic-airlines-会員登録画面-入力画面の作成/

バッキングビーンの作成1
http://subsonic.info/ja/2015/09/03/subsonic-airlines-会員登録画面-バッキングビーンの作成1/

バッキングビーンの作成2
http://subsonic.info/ja/2015/09/06/subsonic-airlines-会員登録画面-バッキングビーンの作成2/

バッキングビーンの作成3
http://subsonic.info/ja/2015/09/11/subsonic-airlines-会員登録画面-バッキングビーンの作成3/

バッキングビーンの作成4
http://subsonic.info/ja/2015/09/13/subsonic-airlines-会員登録画面-バッキングビーンの作成4/

ソースコード
https://github.com/subsonicsystems/subsonic-airlines-members

フォーム入力の検証
ユーザ名フィールドの検証について説明します。

InputView.java

/**
 * Tests if username is valid.
 * 
 * @return true if username is valid; false otherwise.
 */
private boolean isUsernameValid() {

    if (StringUtils.isBlank(user.getUsername())) {
        String message = resourceBundle.getString("user.username.required");
        FacesMessage facesMessage = new FacesMessage(FacesMessage.SEVERITY_ERROR, message, message);
        facesContext.addMessage("form:username", facesMessage);
        return false;
    }

    if (!user.getUsername().matches(User.USERNAME_REGEXP)) {
        String message = resourceBundle.getString("user.username.invalid");
        FacesMessage facesMessage = new FacesMessage(FacesMessage.SEVERITY_ERROR, message, message);
        facesContext.addMessage("form:username", facesMessage);
        return false;
    }

    if (user.getUsername().length() < User.USERNAME_MIN_LENGTH) {
        String message = resourceBundle.getString("user.username.minLength");
        message = message.replace("{min}", String.valueOf(User.USERNAME_MIN_LENGTH));

        FacesMessage facesMessage = new FacesMessage(FacesMessage.SEVERITY_ERROR, message, message);
        facesContext.addMessage("form:username", facesMessage);
        return false;
    }

    if (user.getUsername().length() > User.USERNAME_MAX_LENGTH) {
        String message = resourceBundle.getString("user.username.maxLength");
        message = message.replace("{max}", String.valueOf(User.USERNAME_MAX_LENGTH));
        FacesMessage facesMessage = new FacesMessage(FacesMessage.SEVERITY_ERROR, message, message);
        facesContext.addMessage("form:username", facesMessage);
        return false;
    }

    if (userService.existsUsername(user.getUsername())) {
        String message = resourceBundle.getString("user.username.exists");
        FacesMessage facesMessage = new FacesMessage(FacesMessage.SEVERITY_ERROR, message, message);
        facesContext.addMessage("form:username", facesMessage);
        return false;
    }

    return true;
}

120行目のStringUtilsは、Apache Commons Langのクラスです。isBlankメソッドは、空文字列かどうか検証します。ここで検証対象がuser.getUsername()となっています。これは、input.xhtmlの17行目の<p:inputText id=”username” value=”#{registerInputView.user.username}”/>を指しています。

もしユーザ名が未入力であれば、リソースバンドルからメッセージを取得して、このフィールドにそのメッセージをセットします。121行目でキーがuser.username.requiredのメッセージを取得しています。このキーの値は、「ユーザ名を入力してください」です。

次の行でFacesMessageオブジェクトを作成しています。FacesMessageのコンストラクタの引数は左から重大度、要約メッセージ、詳細メッセージです。ここでは、重大度をSEVERITY_ERRORとし、要約メッセージと詳細メッセージに前行で取得したメッセージをセットしています。

さらに次の行で、input.xhtmlの<h:form id=”form”>の内側の<p:inputText id=”username”/>にFacesMessageオブジェクトをセットしています。ここでセットすることによって、<p:message for=”username”/>でエラーメッセージを表示します。

入力されたユーザ名が空文字列でない場合は、次の検証に進みます。127行では正規表現チェックを行っています。正規表現の文字列は、Userオブジェクトに記述しています。

134行目では、最小文字数のチェックをしています。リソースバンドルには、「ユーザ名を{min}文字以上で入力してください」と書いており、ハードコーディングを防いでいます。そして、最小文字数の値はUserオブジェクトに記述しており、ここで、{min}の部分をUserオブジェクトに記述している値に置き換えています。

143行目は、最大文字数の検証を行っています。

151行目は、入力されたユーザ名が既に登録済みかどうかを検証しています。検証のため、UserServiceクラスのexistsUsernameメソッドを呼び出しています。

パスワードフィールドもユーザ名フィールドと同様に検証を行っています。

InputView.java

/**
 * Tests if password is valid.
 * 
 * @return true if password is valid; false otherwise.
 */
private boolean isPasswordValid() {

    if (StringUtils.isBlank(user.getPassword())) {
        String message = resourceBundle.getString("user.password.required");
        FacesMessage facesMessage = new FacesMessage(FacesMessage.SEVERITY_ERROR, message, message);
        facesContext.addMessage("form:password", facesMessage);
        return false;
    }

    if (!user.getPassword().matches(User.PASSWORD_REGEXP)) {
        String message = resourceBundle.getString("user.password.invalid");
        FacesMessage facesMessage = new FacesMessage(FacesMessage.SEVERITY_ERROR, message, message);
        facesContext.addMessage("form:password", facesMessage);
        return false;
    }

    if (user.getPassword().length() < User.PASSWORD_MIN_LENGTH) {
        String message = resourceBundle.getString("user.password.minLength");
        message = message.replace("{min}", String.valueOf(User.PASSWORD_MIN_LENGTH));
        FacesMessage facesMessage = new FacesMessage(FacesMessage.SEVERITY_ERROR, message, message);
        facesContext.addMessage("form:password", facesMessage);
        return false;
    }

    if (user.getPassword().length() > User.PASSWORD_MAX_LENGTH) {
        String message = resourceBundle.getString("user.password.maxLength");
        message = message.replace("{max}", String.valueOf(User.PASSWORD_MAX_LENGTH));
        FacesMessage facesMessage = new FacesMessage(FacesMessage.SEVERITY_ERROR, message, message);
        facesContext.addMessage("form:password", facesMessage);
        return false;
    }

    return true;
}