Самый простой пользовательский подход, который я когда-либо видел и использовал, - это создание поля <h:inputHidden>
с <f:validator>
, в котором вы ссылаетесь на все задействованные компоненты как <f:attribute>
. Если вы объявите его до компонентов, которые должны быть проверены, то вы можете получить отправленные значения внутри валидатора с помощью UIInput#getSubmittedValue()
.
1011 * Е.Г. *
<h:form>
<h:inputHidden id="foo" value="true">
<f:validator validatorId="fooValidator" />
<f:attribute name="input1" value="#{input1}" />
<f:attribute name="input2" value="#{input2}" />
<f:attribute name="input3" value="#{input3}" />
</h:inputHidden>
<h:inputText binding="#{input1}" value="#{bean.input1}" />
<h:inputText binding="#{input2}" value="#{bean.input2}" />
<h:inputText binding="#{input3}" value="#{bean.input3}" />
<h:commandButton value="submit" action="#{bean.submit}" />
<h:message for="foo" />
</h:form>
(обратите внимание на value="true"
на скрытом вводе; фактическое значение на самом деле не имеет значения, но имейте в виду, что валидатор не обязательно будет запущен, когда он нулевой или пустой, в зависимости от JSF версия и конфигурация)
с
@FacesValidator(value="fooValidator")
public class FooValidator implements Validator {
@Override
public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
UIInput input1 = (UIInput) component.getAttributes().get("input1");
UIInput input2 = (UIInput) component.getAttributes().get("input2");
UIInput input3 = (UIInput) component.getAttributes().get("input3");
// ...
Object value1 = input1.getSubmittedValue();
Object value2 = input2.getSubmittedValue();
Object value3 = input3.getSubmittedValue();
// ...
}
}
Если вы объявите <h:inputHidden>
после компонентов, которые должны быть проверены, то значения участвующих компонентов уже преобразованы и проверены, и вы должны получить их по UIInput#getValue()
или, возможно, UIInput#getLocalValue()
(в случае, если UIInput
не isValid()
) вместо этого.
Смотри также:
В качестве альтернативы, вы можете использовать сторонние теги / компоненты для этого. Например, RichFaces имеет тег <rich:graphValidator>
для этого, Seam3 имеет <s:validateForm>
для этого и OmniFaces имеет несколько стандартных <o:validateXxx>
компонентов для этого, которые все продемонстрированы здесь . OmniFaces использует компонентный подход, при котором работа выполняется в UIComponent#processValidators()
. Он также позволяет настраивать таким образом, чтобы можно было достичь вышеуказанного, как показано ниже:
<h:form>
<o:validateMultiple id="foo" components="input1 input2 input3" validator="#{fooValidator}" />
<h:inputText id="input1" value="#{bean.input1}" />
<h:inputText id="input2" value="#{bean.input2}" />
<h:inputText id="input3" value="#{bean.input3}" />
<h:commandButton value="submit" action="#{bean.submit}" />
<h:message for="foo" />
</h:form>
с
@ManagedBean
@RequestScoped
public class FooValidator implements MultiFieldValidator {
@Override
public boolean validateValues(FacesContext context, List<UIInput> components, List<Object> values) {
// ...
}
}
Единственное отличие состоит в том, что он возвращает boolean
и что сообщение должно быть указано как атрибут message
в <o:validateMultiple>
.