jsf一次验证两个字段

时间:2010-08-13 15:02:44

标签: validation jsf

我可以使用一个验证器验证两个相互依赖的字段吗?

     <h:form>
            <h:inputText value="#{logRegBean.person.name}" >
                <f:validator validatorId="loginCorrectValidator" />
            </h:inputText>
            <h:inputSecret value="#{logRegBean.person.password}" />
            <h:commandButton action="#{logRegBean.login}" />
        </h:form>

我想在数据库中搜索用户,如果有用户,我将测试密码(在db和输入中)是否匹配。但是如何在一个验证器中访问密码字段呢?我试图通过createValueExpression()评估其他字段中的值,但看起来我无法在那段时间访问该值,因为我总是得到空字符串。

3 个答案:

答案 0 :(得分:24)

您可以做的最好的事情是在validate()方法中按UIInput抓取另一个UIViewRoot#findComponent()组件,然后通过UIInput#getSubmittedValue()确定提交的值(当它发生时) 组件树中当前经过验证的组件之后)或UIInput#getValue()(当当前组件之前发生时,因此已经过验证)。

E.g。

public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
    UIInput otherInput = (UIInput) context.getViewRoot().findComponent("clientId");
    String otherValue = (String) otherInput.getSubmittedValue();
    // ...
}

另见:

答案 1 :(得分:9)

JSF中的验证机制旨在验证单个组件。
但是,实际上,在将值传播到模型之前,通常需要确保相关组件具有合理的值 例如,要求用户在单个文本字段中输入日期不是一个好主意 相反,您将使用三个不同的文本字段,分别为日,月和年。

如果用户输入非法日期(例如2月30日),您希望显示验证错误并防止非法数据进入模型。

诀窍是将验证器附加到最后一个组件。在调用其验证器时,前面的组件通过验证并设置了其本地值。最后一个组件已通过转换,转换后的值将作为验证方法的Object参数传递。

当然,您需要访问其他组件。您可以使用包含当前表单的所有组件的辅助bean轻松实现该访问。只需将验证方法附加到辅助bean:

public class BackingBean {

    private int day;
    private int month;
    private int year;

    private UIInput dayInput;
    private UIInput monthInput;
    private UIInput yearInput;

    // PROPERTY: day
    public int getDay() { return day; }
    public void setDay(int newValue) { day = newValue; }

    // PROPERTY: month
    public int getMonth() { return month; }
    public void setMonth(int newValue) { month = newValue; }

    // PROPERTY: year
    public int getYear() { return year; }
    public void setYear(int newValue) { year = newValue; }

    // PROPERTY: dayInput
    public UIInput getDayInput() { return dayInput; }
    public void setDayInput(UIInput newValue) { dayInput = newValue; }

    // PROPERTY: monthInput
    public UIInput getMonthInput() { return monthInput; }
    public void setMonthInput(UIInput newValue) { monthInput = newValue; }

    // PROPERTY: yearInput
    public UIInput getYearInput() { return yearInput; }
    public void setYearInput(UIInput newValue) { yearInput = newValue; }

    public void validateDate(FacesContext context, UIComponent component, Object value) {

       int d = ((Integer) dayInput.getLocalValue()).intValue();
       int m = ((Integer) monthInput.getLocalValue()).intValue();
       int y = ((Integer) value).intValue();

       if (!isValidDate(d, m, y)) {
          throw new ValidatorException(new FacesMessage("Invalid Date"));
       }

    }

    private static boolean isValidDate(int d, int m, int y) {
        //DO YOUR VALIDATION HERE
    }

 }

这是您的JSP

 <html>

   <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
   <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>

    <f:view>

       <head></head>

       <body>

          <h:form>

             <h:panelGrid columns="3">

                <h:inputText value="#{bb.day}"   binding="#{bb.dayInput}" size="2" required="true"/>

                <h:inputText value="#{bb.month}" binding="#{bb.monthInput}" size="2" required="true"/>

                <h:inputText value="#{bb.year}"  binding="#{bb.yearInput}" size="4" required="true" validator="#{bb.validateDate}"/>

                <h:message for="year" styleClass="errorMessage"/>

             </h:panelGrid>

             <h:commandButton value="Submit" action="submit"/>

          </h:form>

       </body>

    </f:view>

 </html>

参考: 核心JavaServer™Faces 作者:DAVID GEARY,CAY HORSTMANN

出版商:Addison Wesley 发布日期:2004年6月15日 ISBN:0-13-146305-5

答案 2 :(得分:0)

我认为SeamFaces's:validateForm feature可能正是您所需要的。 (Seam Faces是一个非常有用的库,它为JSF带来了一些漂亮的基于CDI的功能。)