Статьи

Пользовательский JSF-валидатор для обязательных полей

Компоненты JSF, реализующие интерфейс EditableValueHolder, имеют два атрибута ‘required’ и ‘requiredMessage’ — флаг, указывающий, что пользователь должен ввести / выбрать не пустое значение, и текст для сообщения проверки. Мы можем использовать это, но это недостаточно гибко, мы не можем параметризовать сообщение непосредственно в представлении (facelets или jsp), и мы должны сделать что-то для правильной настройки сообщения. Как насчет пользовательского валидатора, прикрепленного к любому обязательному полю? Мы напишем один. Сначала нам нужно зарегистрировать такой валидатор в библиотеке тегов.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?xml version='1.0'?>
<facelet-taglib version='2.0' ... >
    <namespace>http://ip.client/ip-jsftoolkit/validator</namespace>
    <tag>
        <tag-name>requiredFieldValidator</tag-name>
        <validator>
            <validator-id>ip.client.jsftoolkit.RequiredFieldValidator</validator-id>
        </validator>
        <attribute>
            <description>Resource bundle name for the required message</description>
            <name>bundle</name>
            <required>false</required>
            <type>java.lang.String</type>
        </attribute>
        <attribute>
            <description>Key of the required message in the resource bundle</description>
            <name>key</name>
            <required>false</required>
            <type>java.lang.String</type>
        </attribute>
        <attribute>
            <description>Label string for the required message</description>
            <name>label</name>
            <required>false</required>
            <type>java.lang.String</type>
        </attribute>
    </tag>
</facelet-taglib>

Мы определили три атрибута для достижения высокой гибкости. Простое использование будет

1
2
3
4
<h:outputLabel for='myInput' value='#{text['myinput']}'/>
<h:inputText id='myInput' value='...'>
    <jtv:requiredFieldValidator label='#{text['myinput']}'/>
</h:inputText>

Сам класс валидатора не сложен. В зависимости от параметра «ключ» (ключ требуемого сообщения) и параметра «ярлык» (текст соответствующей метки) существует четыре случая получения сообщения.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
/**
 * Validator for required fields.
 */
@FacesValidator(value = RequiredFieldValidator.VALIDATOR_ID)
public class RequiredFieldValidator implements Validator
{
    /** validator id */
    public static final String VALIDATOR_ID = 'ip.client.jsftoolkit.RequiredFieldValidator';
 
    /** default bundle name */
    public static final String DEFAULT_BUNDLE_NAME = 'ip.client.jsftoolkit.validator.message';
 
    private String bundle;
    private String key;
    private String label;
 
    @Override
    public void validate(FacesContext facesContext,
        UIComponent component, Object value) throws ValidatorException
    {
        if (!UIInput.isEmpty(value)) {
           return;
        }
 
        String message;
        String bundleName;
 
        if (bundle == null) {
           bundleName = DEFAULT_BUNDLE_NAME;
        } else {
           bundleName = bundle;
        }
 
        if (key == null && label == null) {
            message = MessageUtils.getMessageText(
               MessageUtils.getResourceBundle(facesContext, bundleName),
                  'jsftoolkit.validator.emptyMandatoryField.1');
        } else if (key == null && label != null) {
            message = MessageUtils.getMessageText(
               MessageUtils.getResourceBundle(facesContext, bundleName),
                  'jsftoolkit.validator.emptyMandatoryField.2', label);
        } else if (key != null && label == null) {
            message = MessageUtils.getMessageText(
               MessageUtils.getResourceBundle(facesContext, bundleName), key);
        } else {
            message = MessageUtils.getMessageText(
               MessageUtils.getResourceBundle(facesContext, bundleName), key, label);
        }
 
        throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_WARN, message, StringUtils.EMPTY));
        
        // getter / setter
        ...
    }
}

MessageUtils — это служебный класс для получения ResourceBundle и текста сообщения. Нам также нужно два текста в комплекте ресурсов (файл свойств)

1
2
jsftoolkit.validator.emptyMandatoryField.1=Some required field is not filled in.
jsftoolkit.validator.emptyMandatoryField.2=The required field '{0}' is not filled in.

и следующий контекстный параметр в web.xml

1
2
3
4
<context-param>
    <param-name>javax.faces.VALIDATE_EMPTY_FIELDS</param-name>
    <param-value>true</param-value>
</context-param>

Это решение не является идеальным, потому что нам нужно дважды определить текст метки (например, # {text [‘myinput’]}) и прикрепить валидатор к каждому полю для проверки. Лучший и общий валидатор для нескольких полей будет представлен в следующем посте. Будьте на связи!

Ссылка: Пользовательский валидатор JSF для обязательных полей от нашего партнера по JCG Олега Вараксина из блога « Мысли о разработке программного обеспечения» .