Статьи

Параметризация пользовательского валидатора в JSF 2

Написание собственного валидатора в JSF 2 не является сложной задачей. Вы реализуете интерфейс Validator , добавляете аннотацию @FacesValidator и вставляете объявление валидатора вface -config.xml , вот и все. Кусок торта. Но давайте рассмотрим следующий сценарий:

Вам нужен специальный валидатор даты, скажем, проверка этой даты с помощью rich: календарь не в прошлом. Таким образом, мы помещаем компонент календаря с валидатором внутри.

1
2
3
<rich:calendar value="#{fieldValue}" id="dateField" datePattern="yyyy/MM/dd">
        <f:validator validatorId="dateNotInThePast"/>
    </rich:calendar>

И наш валидатор может выглядеть так:

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
@FacesValidator("dateNotInThePast")
public class DateNotInThePastValidator implements Validator {
 
  @Override
  public void validate(FacesContext facesContext, UIComponent uiComponent, Object value)
                                                              throws ValidatorException {
    if (ObjectUtil.isNotEmpty(value)) {
      checkDate((Date)value, uiComponent, facesContext.getViewRoot().getLocale());
    }
  }
 
  private void checkDate(Date date, UIComponent uiComponent, Locale locale) {
    if(isDateInRange(date) == false) {
      ResourceBundle rb = ResourceBundle.getBundle("messages", locale);
      String messageText = rb.getString("date.not.in.the.past");
      throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR,
                                     messageText, messageText));
    }
  }
 
  private boolean isDateInRange(Date date) {
    Date today = new DateTime().withTime(0, 0, 0, 0).toDate();
    return date.after(today) || date.equals(today);
  }
}

И если мы предоставим значение ключа в файле свойств, мы увидим что-то вроде этого:

Итак, похоже, что у нас есть рабочий и готовый к использованию пользовательский валидатор.

Эта проблема

Но в то время как наша форма становится все более сложной, мы можем столкнуться с проблемой, описанной на экране ниже:

Итак, проблема в том, как пользователь может определить, какая дата действительна, а какая нет? Наш валидатор использует один и тот же ключ свойства для отображения обоих сообщений об ошибках.

Решение

Нам нужно как-то предоставить метку проверенного поля нашему пользовательскому валидатору. И, что удивительно для JSF, это может быть достигнуто довольно легко. Единственный улов в том, что вы должны знать, как это сделать :)

Поэтому в Java Server Faces мы можем параметризовать компоненты с атрибутами (тег f: attribute ). Поэтому мы добавляем атрибут к rich: calendar, а затем читаем это переданное значение в валидаторе, назначенном этому календарному полю. Итак, теперь наши компоненты календаря должны выглядеть так:

1
2
3
4
<rich:calendar value="#{fieldValue}" id="dateField" datePattern="yyyy/MM/dd">
        <f:validator validatorId="dateNotInThePast"/>
        <f:attribute name="fieldLabel" value="Date field 2" />
    </rich:calendar>

И в нашем Java-классе валидатора мы могли получить это значение, используя uiComponent.getAttributes (). Get (“fieldLabel”);

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
private void checkDate(Date date, UIComponent uiComponent, Locale locale) {
        if(isDateInRange(date) == false) {
            ResourceBundle rb = ResourceBundle.getBundle("messages", locale);
            String messageText = getFieldLabel(uiComponent) +" " + rb.getString(getErrorKey());
 
            throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR,
                                            messageText, messageText));
        }
    }
 
    protected String getFieldLabel(UIComponent uiComponent) {
        String fieldLabel = (String) uiComponent.getAttributes().get("fieldLabel");
 
        if(fieldLabel == null) {
            fieldLabel = "Date" ;
        }
 
        return fieldLabel;
    }

Наше значение свойства error должно иметь значение, которое не может быть в прошлом, так как в начале сообщения об ошибке будет добавлена ​​метка даты или поля.

И рабочий пример должен показать что-то похожее на этот экран:

Ссылка: Параметризация пользовательского валидатора в JSF 2 от нашего партнера по JCG Томаша Дзюрко в блоге Code Hard Go Pro

Статьи по Теме :