【问题标题】:How validate two password fields by ajax?如何通过ajax验证两个密码字段?
【发布时间】:2011-11-21 08:07:42
【问题描述】:

我正在尝试使用 JSF 验证两个密码字段,但到目前为止效果不佳,我在 google 上搜索它,但所有内容都是关于 JSF 1.2 的,而且相当混乱,我使用的是 JSF 2.0。

这就是我目前正在做的事情:

        <h:outputLabel for="password" value="Password:" />
        <h:inputSecret id="password"  value="#{register.user.password}"  >  
            <f:ajax    event="blur"   listener="#{register.validatePassword}" render="m_password" />
        </h:inputSecret>
        <rich:message id="m_password" for="password"/>

        <h:outputLabel for="password_2" value="Password (again):" />
        <h:inputSecret id="password_2"  value="#{register.user.password_2}"  >  
            <f:ajax    event="blur"     listener="#{register.validatePassword}" />
        </h:inputSecret>

这就是我的控制器:

public void validatePassword() {
    FacesMessage message;

    if (!user.getPassword().equals(user.getPassword_2()) ){
        message = new FacesMessage(FacesMessage.SEVERITY_ERROR, null, "different password");
    }else{
        message = new FacesMessage(FacesMessage.SEVERITY_INFO, null, "ok");
    }

    FacesContext.getCurrentInstance().addMessage("form:password", message);
}

有什么想法吗?

【问题讨论】:

  • 你是什么意思它工作但不太好?慢吗?不确定我是否了解您想要更改的内容以及原因。
  • 嗨@jdias,我的意思是没有按预期的方式工作。谢谢,这可能有点令人困惑。

标签: jsf jsf-2 passwords validation


【解决方案1】:

您可以使用Primefaces p:password 标签。请看演示example。它有 ma​​tch 属性,应该是确认密码的 id。

<p:panel header="Match Mode">  
    <p:messages id="messages" showDetail="true" autoUpdate="true"/>  

    <h:panelGrid columns="2" id="matchGrid">                     
                <h:outputLabel for="pass" value="Password " />  
                <p:password id="pass" value="#{passwordBean.password}" match="confirmPass"   required="true"/>  

                <h:outputLabel for="confirmPass" value="Confirm Password " />  
                <p:password id="confirmPass" value="#{passwordBean.confirmPassword}" required="true"/>  
    </h:panelGrid>  

    <p:commandButton id="saveButton" update="matchGrid" value="Save" />  
</p:panel>

【讨论】:

    【解决方案2】:

    首先,使用 real Validator 来验证输入。不要在动作事件方法中这样做。

    至于您的具体问题,您只需在&lt;f:ajax&gt;execute 属性中指定both 字段,即默认为仅当前组件。如果您将验证器附加到第一个输入并将第二个输入的值作为&lt;f:attribute&gt; 发送,那么您将能够在验证器中获取它。您可以使用binding 属性将组件绑定到视图。这样您就可以通过UIInput#getSubmittedValue() 传递其提交的值。

    这是一个启动示例:

    <h:outputLabel for="password" value="Password:" />
    <h:inputSecret id="password" value="#{bean.password}" required="true">
        <f:validator validatorId="confirmPasswordValidator" />
        <f:attribute name="confirm" value="#{confirmPassword.submittedValue}" />
        <f:ajax event="blur" execute="password confirm" render="m_password" />
    </h:inputSecret>
    <h:message id="m_password" for="password" />
    
    <h:outputLabel for="confirm" value="Password (again):" />
    <h:inputSecret id="confirm" binding="#{confirmPassword}" required="true">
        <f:ajax event="blur" execute="password confirm" render="m_password m_confirm" />
    </h:inputSecret>
    <h:message id="m_confirm" for="confirm" />
    

    (请注意,我在两个组件中都添加了required="true",并且还请注意,您不一定需要将确认密码组件值绑定到托管 bean 属性,反正在那里毫无价值)

    使用此验证器

    @FacesValidator("confirmPasswordValidator")
    public class ConfirmPasswordValidator implements Validator {
    
        @Override
        public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
            String password = (String) value;
            String confirm = (String) component.getAttributes().get("confirm");
    
            if (password == null || confirm == null) {
                return; // Just ignore and let required="true" do its job.
            }
    
            if (!password.equals(confirm)) {
                throw new ValidatorException(new FacesMessage("Passwords are not equal."));
            }
        }
    
    }
    

    【讨论】:

    • 绑定="#{confirmPassword}" 中的confirmPassword 是什么?
    • @Jsword:它将通过给定的标识符将组件绑定到视图,以便视图中其他位置的#{confirmPassword} 可以使用它(例如在第一个字段的&lt;f:attribute&gt; 中,以便它可以在验证器中获取)。
    • 我现在明白了'绑定'BalusC的功能,谢谢老兄的帮助。
    • 不客气。顺便说一句,您也可以将其绑定到 bean 属性。然后它将是一个UIInput 属性。但在这种情况下这不是必需的(它会破坏 viewscoped bean)。
    【解决方案3】:

    使用 seam 2,您拥有组件 &lt;s:validateEquality&gt;,您无需编写代码。对于 JSF2,您拥有 Seam 3 模块,特别是 Faces module 和跨字段表单验证。一个例子:

    首先你必须使用 s:validateForm 标签:

    <h:form id="passwordForm">
        <h:inputSecret id="newPassword"
            required="true"
            redisplay="true"
            value="#{passwordController.newPassword}">
        </h:inputSecret>            
        <h:inputSecret id="confirmationPassword"
            value="#{passwordController.confirmPassword}"
            required="true"
            redisplay="true">
        </h:inputSecret>
        <h:commandButton id="submit" value="Submit" action="#{passwordController.submitPassword}" />
        <s:validateForm validatorId="passwordValidator" />
    </h:form>
    

    上面密码表单对应的验证器如下所示:

    @FacesValidator("PasswordValidator")
    public class PasswordValidator implements Validator
    {
       @Inject
       @InputField
       private String newPassword;
    
       @Inject
       @InputField
       private String confirmPassword;
    
       @Override
       public void validate(final FacesContext context, final UIComponent comp, final Object values) throws ValidatorException
       {
          if (!confirmPassword.equals(newPassword))
          {
             throw new ValidatorException(new FacesMessage("Passwords do not match!"));
          }
       }
    }
    

    【讨论】:

    • 我在纯 JSF2 中寻找类似的解决方案,但找不到。你知道这是否存在于 JSF2 中吗?尤其是@InputField 注解似乎很有用。
    猜你喜欢
    • 2013-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-10
    • 1970-01-01
    • 2014-07-26
    • 1970-01-01
    相关资源
    最近更新 更多