jsf проверять два поля за один раз [дублировать]

17

Можно ли проверить два взаимозависимых поля с одним валидатором?

     <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 и введенные). Но как я могу получить доступ даже к полю пароля в одном валидаторе? Я попытался оценить значение int в другом поле через createValueExpression() , но похоже, что я не могу получить доступ к значению за это время, так как всегда получаю пустые строки.

    
задан coubeatczech 13.08.2010 в 17:02
источник

3 ответа

22

Лучшее, что вы можете сделать, это захватить другой UIInput UIViewRoot#findComponent() внутри метода validate() , а затем определить переданное значение либо UIInput#getSubmittedValue() (когда происходит после текущий проверенный компонент в дереве компонентов) или UIInput#getValue() (когда это происходит до текущего компонента и, следовательно, уже проверено).

например.

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

См. также:

ответ дан BalusC 13.08.2010 в 17:35
источник
  • У меня такая же проблема. Я добавил код кода в свой код. Но я получил исключение nullpointer. Можете ли вы сказать мне, почему? –  Kayser 12.08.2013 в 17:33
  • @Kayser: Обычно вы получаете это, когда код пытается получить доступ / ссылаться на ссылку, которая на самом деле является нулевой. См. Также docs.oracle.com/javase/7/docs/api/java/lang/... –  BalusC 12.08.2013 в 17:35
  • DateIntervalValidator не может быть null public void validate (FacesContext context, компонент UIComponent, значение Object) {UIInput fromComponent = (UIInput) context.getViewRoot (). findComponent ("from"); Дата fromDate = (Дата) fromComponent.getSubmittedValue (); <rich: calendar id="from"> <f: validator binding="# {dateFieldValidator}" /> <f: attribute name="fromDate" value="# {msg ['from']}" /> </rich: calendar> <rich: calendar id="until"> <f: validator binding="# {dateFieldValidator}" /> <f: validator binding="# {dateIntervalValidator}" /> <f: attribute name="untilDate "value=" # {msg ['до']} "/> </rich: calendar> –  Kayser 13.08.2013 в 09:34
  • @Kayser try findComponent ("<formId>: from"), где <formId> - это фактический идентификатор вашей формы (омнитовая угловая скобка). не ешьте мясо. –  demonz demonz 13.02.2014 в 17:51
  • Обратите внимание, что с абсолютными идентификаторами вам нужно: перед идентификатором в UIViewRoot # findComponent (). Похоже, что он соответствует тем же правилам, что и поиск XHTML ID, согласно документации, я думаю. –  Andrew 10.10.2017 в 14:52
9

Механизм проверки в JSF был разработан для проверки одного компонента.
Однако на практике вам часто необходимо убедиться, что связанные компоненты имеют разумные значения, прежде чем позволить значениям распространяться в модель.
Например, не рекомендуется просить пользователей вводить дату в одно текстовое поле.
Вместо этого вы будете использовать три разных текстовых поля: день, месяц и год.

Если пользователь вводит нелегальную дату, например 30 февраля, вы хотите показать ошибку проверки и предотвратить ввод незаконных данных в модель.

Фокус в том, чтобы прикрепить валидатор к последнему из компонентов. К моменту его проверки валидатор предыдущие компоненты прошли проверку и установили локальные значения. Последний компонент прошел преобразование, а преобразованное значение передается как параметр Object метода проверки.

Конечно, вам нужно иметь доступ к другим компонентам. Вы можете легко достичь этого доступа, используя бэк-компонент, содержащий все компоненты текущей формы. Просто прикрепите метод проверки к бэк-файлу:

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 ДЭВИД ГЕЙАР, КЕЙ ХОРСТМАНН

Издатель: Addison Wesley Паб Дата: 15 июня 2004 г. ISBN: 0-13-146305-5

    
ответ дан Kerem Baydoğan 15.08.2010 в 22:18
источник
  • Итак, что произойдет, если вы введете действительную дату .e.g 28 фев 2017, но затем измените день на 30? –  DD. 06.09.2017 в 23:52
0

Я думаю, что SeamFaces s:validateForm feature может быть именно то, что вам нужно. ( Seam Faces - очень полезная библиотека, которая привносит в JSF отличные функции на основе CDI.)

    
ответ дан Nick 12.01.2013 в 00:35
источник
  • Может ли кто-либо предоставить или связать информацию о том, откуда находится s: validateForm, после того, как Seam был отменен, и проверка была перенесена на beanvalidation.org [seamframework.org/Seam3] –  Karl Richter 19.06.2014 в 21:46
  • @KarlRichter, насколько я знаю, проверка формы еще не установлена ​​в Apache DeltaSpike, преемнике Seam. На данный момент вы все равно можете использовать Seam's: validateForm или RichFaces: richValidator. –  Nick 19.06.2014 в 23:41