JSF 2.0:コードを記述せずに 2 つの InputSecret フィールドが等しいことを検証します (パスワードを確認します)。
-
04-10-2019 - |
質問
JSF 2.0 と Glassfish を使用して純粋な JavaEE6 アプリケーションを開発しています。私の JSF 実装は Primefaces です (Glassfish によって提供される Mojarra のほかに)。
JSF フォーム内の 2 つのパスワード フィールドの値が等しいかどうかを確認したいと考えています。Seam にはきちんとしたコンポーネントがあります <s:validateEquality for="pw1"/>
。Seam を使わずに、JSF (または JSF ライブラリのコンポーネント) だけを使用して同じことをしたいと考えています。これまでは、カスタムバリデーターを使用してフォームを検証する例のみを見てきました。しかし、Java コードや Javascript コードを書かずにフィールドを比較したいと考えています。それは可能ですか?
Seam では次のようになります。
...
<h:inputSecret id="passwort" value="#{personHome.instance.password}"
redisplay="true" required="true">
<f:validateLength minimum="8"/>
<a:support event="onblur" reRender="passwortField" bypassUpdates="true" ajaxSingle="true" />
</h:inputSecret>
...
<h:inputSecret id="passwort2" required="true" redisplay="true">
<!-- find the JSF2.0-equivalent to this tag: -->
<s:validateEquality for="passwort"/>
<a:support event="onblur" reRender="passwort2Field" bypassUpdates="true" ajaxSingle="true" />
</h:inputSecret>
...
解決 5
これが私がついにやった方法です。それはそれが短くて簡単だからです。唯一の問題は、それが実際に再利用可能ではないことですが、私はこれを1つのケースでのみ必要とするので、私はむしろいくつかのlocを保存してこの方法でそれを行います。私の見解からのスニペット:
<h:inputSecret id="password" value="#{personHome.person.password}">
<f:ajax event="blur" render="passwordError" />
</h:inputSecret>
<h:message for="password" errorClass="invalid" id="passwordError" />
<h:inputSecret id="password2" validator="#{personHome.validateSamePassword}">
<f:ajax event="blur" render="password2Error" />
</h:inputSecret>
<h:message for="password2" errorClass="invalid" id="password2Error" />
私のバッキングビーン(ただ重要な部分):
@Named @ConversationScoped
public class PersonHome {
private Person person;
public Person getPerson() {
if (person == null) return new Person();
else return person;
}
public void validateSamePassword(context:FacesContext, toValidate:UIComponent, value:Object) {
String confirmPassword = (String)value;
if (!confirmPassword.equals(person.getPassword()) {
FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Passwords do not match!", "Passwords do not match!")
throw new Validatorexception(message);
}
}
他のヒント
Seam3はモジュールに面しています 差し迫ったAlpha3リリースで「クロスフィールドフォーム検証」をサポートします。これは最小限のコードソリューションの最善の策です。これを参照してください ブログ ハウツーのために。
あるいは、F:属性タグを使用して別のフォームフィールドのclientIDをカスタムバリーターに渡すことにより、このプログラムでこれを実行し、カスタムバリーターに渡されたuicomponentを使用してIDによって提出された他のファイルにアクセスします。
これがフェイスラットファイルです:
<h:outputLabel value="Enter your email address" rendered="#{!cc.attrs.registration.subRegistration}" />
<h:inputText label="Email" id="textEmail1" value="#{cc.attrs.registration.email}" rendered="#{!cc.attrs.registration.subRegistration}" required="true" maxlength="128" size="35"></h:inputText>
<h:message for="textEmail1" rendered="#{!cc.attrs.registration.subRegistration}"></h:message>
<h:outputLabel value="Re-enter your email address confirmation:" rendered="#{!cc.attrs.registration.subRegistration and cc.attrs.duplicateEmailRequired}" />
<h:inputText label="Email repeat" id="textEmail2" rendered="#{!cc.attrs.registration.subRegistration and cc.attrs.duplicateEmailRequired}" maxlength="64" size="35">
<f:validator validatorId="duplicateFieldValidator" />
<f:attribute name="field1Id" value="#{component.parent.parent.clientId}:textEmail1" />
</h:inputText>
<h:message for="textEmail2" rendered="#{!cc.attrs.registration.subRegistration and cc.attrs.duplicateEmailRequired}"></h:message>
これがバリデータークラスです:
package ca.triumf.mis.trevents.jsf.validator;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.component.UIInput;
import javax.faces.context.FacesContext;
import javax.faces.validator.FacesValidator;
import javax.faces.validator.Validator;
import javax.faces.validator.ValidatorException;
@FacesValidator(value="duplicateFieldValidator")
public class DuplicateFieldValidator implements Validator {
@Override
public void validate(FacesContext context, UIComponent component, Object value)
throws ValidatorException {
// Obtain the client ID of the first field from f:attribute.
System.out.println(component.getFamily());
String field1Id = (String) component.getAttributes().get("field1Id");
// Find the actual JSF component for the client ID.
UIInput textInput = (UIInput) context.getViewRoot().findComponent(field1Id);
if (textInput == null)
throw new IllegalArgumentException(String.format("Unable to find component with id %s",field1Id));
// Get its value, the entered text of the first field.
String field1 = (String) textInput.getValue();
// Cast the value of the entered text of the second field back to String.
String confirm = (String) value;
// Check if the first text is actually entered and compare it with second text.
if (field1 != null && field1.length() != 0 && !field1.equals(confirm)) {
throw new ValidatorException(new FacesMessage("E-mail addresses are not equal."));
}
}
}
この非常にシンプルな方法でPrimeFacesタグを使用できます。
<p:password id="password" value="#{bean.password}" match="repeated_password" />
<p:password id="repeated_password" value="#{bean.password}" />
両方の回答の混合物を使用して成功する必要がありました。
ifischersショートソリューションを使用しましたが、Beanパスワードフィールドはnullでした。
そこで、ブライアン・リーザームの線を使用して、コンテキストからuiinputを取得しました。
public void passwordValidator(FacesContext context, UIComponent toValidate, Object value) {
UIInput passwordField = (UIInput) context.getViewRoot().findComponent("registerForm:password");
if (passwordField == null)
throw new IllegalArgumentException(String.format("Unable to find component."));
String password = (String) passwordField.getValue();
String confirmPassword = (String) value;
if (!confirmPassword.equals(password)) {
FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Passwords do not match!", "Passwords do not match!");
throw new ValidatorException(message);
}
}
JSFユーティリティライブラリを使用している場合 オムニフェイス, 、それからあなたは使うことができます <o:validateEqual>
. 。カスタムメッセージを設定することもできます。の ショーケース には、パスワード確認を検証する一般的な使用例を示す実際の例があります。バリデーターを呼び出す前にモデルを更新するために ajax を使用する必要さえありません( あなた自身のアプローチ します)。
最低限必要なコードは次のとおりです。
<h:inputSecret id="password" value="#{personHome.person.password}" />
<h:message for="password" />
<h:inputSecret id="password2" />
<h:message for="password2" />
<o:validateEqual components="password password2"
message="Passwords do not match!" showMessageFor="password2" />
Java コードは必要ありません。
Apache Myfaces extvalで簡単に行うことができます。
編集: :読む前に、このソリューションは完全に機能し、答えは2012年7月からのものであることを考えてください。世界は変わり、今ではより良いコンポーネントとソリューションがあります。
解決策がなければ、私は醜い方法で検証を行うことを余儀なくされました(推奨されません)。少なくとも、より良い解決策が見つかるまで機能します。
アクションを返す方法では、両方の値をチェックします。異なる値の場合、コンテキストにエラーメッセージを追加し、nullをナビゲーションハンドラーに返します。
package com.jsf.beans.user;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.component.html.HtmlInputSecret;
import org.apache.commons.lang.StringUtils;
import com.pichler.jsf.beans.base.JsfViewBean;
@ManagedBean(name = "changePassword")
@RequestScoped
public class ChangePassword extends JsfViewBean {
private HtmlInputSecret inputSecret1, inputSecret2;
/**
* @return the inputSecret1
*/
public HtmlInputSecret getInputSecret1() {
return inputSecret1;
}
/**
* @param inputSecret1
* the inputSecret1 to set
*/
public void setInputSecret1(HtmlInputSecret inputSecret1) {
this.inputSecret1 = inputSecret1;
}
/**
* @return the inputSecret2
*/
public HtmlInputSecret getInputSecret2() {
return inputSecret2;
}
/**
* @param inputSecret2
* the inputSecret2 to set
*/
public void setInputSecret2(HtmlInputSecret inputSecret2) {
this.inputSecret2 = inputSecret2;
}
private String password1, password2;
public String alterar() {
if (!StringUtils.equals(password1, password2)) {
addErrorMessage(inputSecret1.getClientId(),
"As senhas não coincidem");
addErrorMessage(inputSecret2.getClientId(),
"As senhas não coincidem");
return null;
}
return null;
}
/**
* @return the password1
*/
public String getPassword1() {
return password1;
}
/**
* @param password1
* the password1 to set
*/
public void setPassword1(String password1) {
this.password1 = password1;
}
/**
* @return the password2
*/
public String getPassword2() {
return password2;
}
/**
* @param password2
* the password2 to set
*/
public void setPassword2(String password2) {
this.password2 = password2;
}
}
*jsfviewbeanは、「addmessages」など、いくつかの一般的な方法を持つクラスにすぎません。