JSF не поддерживает перекрестную проверку, есть ли обходной путь? - PullRequest
35 голосов
/ 08 июня 2011

JSF 2.0 позволяет проверять ввод только в одном поле, например, проверить, является ли он определенной длины. Он не позволяет вам иметь форму с надписью «введите город и штат или просто введите почтовый индекс».

Как ты справился с этим? Меня интересуют только ответы, которые касаются этапа проверки JSF. Я не заинтересован в размещении логики проверки в управляемых компонентах.

Ответы [ 2 ]

56 голосов
/ 08 июня 2011

Самый простой пользовательский подход, который я когда-либо видел и использовал, - это создание поля <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>.

1 голос
/ 02 мая 2013

Apache ExtVal здесь не упоминается.

В нем есть несколько перекрестных проверок (среди прочих проверок, которые могут быть полезны):

https://cwiki.apache.org/confluence/display/EXTVAL/Property+Validation+Usage#PropertyValidationUsage-CrossValidation

...