1

我是 JSF 的新手,正在经历一个 JSF 应用程序。

我想验证空白字符串的一个密码字段。

我知道不是在 Javascript 中执行此操作,而是调用一个函数进行验证。

我的需要是,如果密码字段的值为空白,那么它会从验证器函数进行验证,直到现在它运行正常,但在验证之后,当它到达 UI bav=ck 时,密码字段应该为空。

如果密码字段为空(仅包含空格),那么我希望将其设置为空白,否则保持数据不变。

我到现在为止的尝试,JSF 视图页面 singin.xhtml

                    <h:outputText styleClass="outputBox" style="margin: 3px;"
                        value="Password" />
                    <h:inputSecret id="password" required="true" 
                        requiredMessage="Please enter your password"
                        value="#{userActionManager.dto.password}" 
                        validator="#{userActionManager.validateSamePassword}">

                            <a4j:ajax event="change" execute="@this" bypassUpdates="true" />
                    </h:inputSecret>

验证器方法。

    public void validateSamePassword(FacesContext fc, UIComponent component, Object obj) {
         System.out.println("UserActionManager.validateSamePassword()");

         String confirmPassword = (String)obj;
         System.out.println("Password is :" + confirmPassword);
            if(confirmPassword!=null && confirmPassword.trim().equals("")) {
              FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Password cannot be blank", " detail Passwords do not match!");

//            System.out.println(component.getFamily());
//            String field1Id = (String) component.getAttributes().get("password");

              // Find the actual JSF component for the client ID.
//            UIInput textInput = (UIInput) fc.getViewRoot().findComponent("password");
//            textInput.setValue("");

              dto.setPassword(null);

              throw new ValidatorException(message);
            }else{
                dto.setPassword(confirmPassword);
            }
    }

我试过选项 dto.setPassword(null); 但是当它返回查看时,密码字段中的空格仍然存在,我必须手动删除。

我错过了什么?

4

2 回答 2

1

如果组件被标记为无效,则它不会重新显示模型值(在您的情况下,来自 的值dto)。相反,它将重新显示其提交的值。您只需要将提交的值设置为空字符串。

代替

dto.setPassword(null);

经过

((UIInput) component).setSubmittedValue("");
于 2013-03-17T15:05:46.523 回答
1

在您的验证器中,调用作为参数传递 resetValue()的实例UIComponent

public void validateSamePassword(FacesContext fc, UIComponent component, Object obj) {
     System.out.println("UserActionManager.validateSamePassword()");

     String confirmPassword = (String)obj;
     System.out.println("Password is :" + confirmPassword);
        if(confirmPassword!=null && confirmPassword.trim().equals("")) {
          FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR,   "Password cannot be blank", " detail Passwords do not match!");

          component.resetValue();

          throw new ValidatorException(message);
        }else{
            dto.setPassword(confirmPassword);
        }
}

dto.setPassword(null)不会影响密码框中的值,因为输入组件旨在保留导致它们验证失败的值。resetValue()是一种将导致组件将其值重置为未初始化状态的方法

编辑:上面的解决方案过早地重置输入值。ValidationException从技术上讲,在抛出a 之前验证不会失败。要有效地重置字段:

  1. 定义一个监听事件,只有在验证失败后才会重置组件的值

    public void resetPwd(ComponentSystemEvent evt) throws IOException {
    HtmlInputSecret txt = (HtmlInputSecret) evt.getComponent();
    if(!txt.isValid()){ //make sure that the validation failed 
        txt.resetValue();
       }
    
    }
    
  2. 将侦听器事件附加到postValidate密码组件上的事件侦听器。这将确保仅在验证失败后才重置该值。

      <h:inputSecret id="password" required="true" 
                    requiredMessage="Please enter your password"
                    value="#{userActionManager.dto.password}" 
                    validator="#{userActionManager.validateSamePassword}">
                        <f:event name="postValidate" listener="#{userActionManager.resetPwd}"/>
                        <a4j:ajax event="change" execute="@this" bypassUpdates="true" />
                </h:inputSecret>
    

这里的关键是在正确的时间重置值。其他时间选项包括preRenderView事件和postAddToView事件。一切都在时机

于 2013-03-17T07:27:25.450 回答