@NotNull Bean Validation игнорируется для viewParam

Проблема

Я пытаюсь проверить обязательный параметр запроса GET.

В представлении я добавил соответствующий тег viewParam.

<f:metadata>
    <f:viewParam name="customerId" value="#{customerDetailBean.customerId}"/>
</f:metadata>

И мой компонент CDI выглядит так

@Model
public class CustomerDetailBean {

    @NotNull
    private Integer customerId;

    public Integer getCustomerId() {
        return customerId;
    }

    public void setCustomerId(Integer customerId) {
        this.customerId = customerId;
    }
}

Когда я использую следующий запрос, проверка работает нормально, и отображается ожидаемое сообщение проверки.

http://localhost:8080/getsupport/customerdetail.jsf?customerId=

Однако, когда я изменяю запрос, удаляя параметр customerId, проверка пропускается и сообщение не отображается.

http://localhost:8080/getsupport/customerdetail.jsf

Есть ли способ заставить его работать так, как ожидалось?

Временное решение

Я изменил объявление viewParam на

<f:metadata>
    <f:viewParam name="customerId" value="#{customerDetailBean.customerId}" required="true" />
</f:metadata>

Эта обновленная версия отлично работает со вторым запросом. В любом случае я бы предпочел использовать проверку bean.

Мои настройки

  • Мохарра JSF 2.2.7
  • Сварка 2.2.1.Окончательная
  • Hibernate Validator 5.1.1.Final
  • Томкэт 7.0.54

веб.xml

<context-param>
    <param-name>javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL</param-name>
    <param-value>true</param-value>
</context-param>

person Thomas    schedule 09.07.2014    source источник


Ответы (2)


Это, к сожалению, "работает как задумано". Вся проверка пропускается, если ничего не отправлено. Только <f:viewParam required> имеет особое отношение. Это также считается, когда ничего не было представлено. См. также UIViewParameter#processValidators() javadoc и исходный код.

В системе отслеживания проблем Mojarra я могу найти только проблема 3058 как связанная проблема, при этом <f:validateRequired> не рассматривается. Технически это точно такая же проблема, с которой вы столкнулись с @NotNull. Я создал для этого issue 3339.

А пока лучше всего вернуться к required="true". Пользовательский компонент также может, но, насколько я понимаю, это не будет тривиально.


Обновление: в конце концов, исправление относительно простое и было реализовано в OmniFaces <o:viewParam> в текущей версии моментального снимка 2.0.

person BalusC    schedule 16.07.2014
comment
Спасибо BalusC за очень четкое объяснение, включая ссылку на исходный код. Я очень ценю, что вы создали задачу в трекере. Я бы хотел, чтобы это работало, как ожидалось, в будущем. - person Thomas; 16.07.2014
comment
Я только что исправил это для OmniFaces 2.0 (моментальный снимок). Смотрите обновление ответа. - person BalusC; 16.07.2014

До JSF 2.0 проверка просто не выполнялась для полей, значения которых были пустыми или нулевыми. JSF 2.0 немного меняет это поведение по умолчанию. Если среда выполнения JSF выполняется в среде, которая поддерживает проверку компонентов, пустые поля проверяются по умолчанию. В остальном поведение такое же, как и до JSF 2.0: пустые поля не проверяются.

Поскольку Tomcat(& Jetty) не является серверным компонентом, совместимым с J2EE, проверка bean-компонентов по умолчанию не включена. Вот почему ваша проверка пропускается.

Чтобы заставить JSF проверять пустые поля, добавьте это в свой файл web.xml:

 <context-param>
    <param-name>javax.faces.VALIDATE_EMPTY_FIELDS</param-name>
    <param-value>true</param-value>
 </context-param>   

Проверка Bean (JSR 303) может быть настроена на сервере, не совместимом с j2ee, с минимальной конфигурацией (я никогда этого не настраивал :)). Каким-то образом вы включили проверку bean-компонента, и у вас нет выше параметра контекста, тогда среда выполнения jsf будет считать его истинным и проверять пустые и нулевые поля для проверки.

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

И убедитесь, что для параметра контекста javax.faces.validator.DISABLE_DEFAULT_BEAN_VALIDATOR не установлено значение true в web.xml.

Чтобы просмотреть список этих параметров, см.
Обзор всех имен и значений параметров контекста web.xml, связанных с JSF

Надеюсь это поможет.

person Srikanth Ganji    schedule 10.07.2014
comment
Спасибо за ваш ответ, Шрикант. Я добавил параметр VALIDATE_EMPTY_FIELDS в web.xml, но это не сработало. Во всяком случае, настройка проверки bean-компонента кажется в порядке. Параметры запроса проверяются, как и ожидалось (например, ?customerId= приводит к сообщению об ошибке). Единственный случай, который не работает, — это полное отсутствие параметров. В этом случае @NotNull не оценивается. - person Thomas; 10.07.2014
comment
Я не слишком беспокоюсь о накладных расходах производительности при использовании проверки bean-компонентов. Конечно, вы правы, говоря, что отражение добавляет некоторые дополнительные затраты. В любом случае, JSF во многих случаях использует отражение (например, привязки значений). - person Thomas; 10.07.2014