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 и введенные). Но как я могу получить доступ даже к полю пароля в одном валидаторе? Я попытался оценить значение int в другом поле через createValueExpression()
, но похоже, что я не могу получить доступ к значению за это время, так как всегда получаю пустые строки.
Ответы
Ответ 1
Лучшее, что вы можете сделать, это захватить другой компонент 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();
// ...
}
См. также:
Ответ 2
Механизм проверки в JSF был разработан для проверки одного компонента.
Однако на практике вам часто необходимо убедиться, что связанные компоненты имеют разумные значения, прежде чем позволить значениям распространяться в модель.
Например, не рекомендуется просить пользователей вводить дату в одно текстовое поле.
Вместо этого вы будете использовать три разных текстовых поля: день, месяц и год.
Если пользователь вводит нелегальную дату, например 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
ДЭВИД ГЕЙАР, КЕЙ ХОРСТМАНН
Издатель: Addison Wesley
Паб Дата: 15 июня 2004 г.
ISBN: 0-13-146305-5
Ответ 3
Я думаю, что функция SeamFaces s:validateForm
может быть именно тем, что вам нужно. ( Seam Faces - очень полезная библиотека, которая привносит в JSF отличные функции на основе CDI.)