Ошибка проверки: значение недействительно

У меня проблема с ap: selectOneMenu, независимо от того, что я делаю, я не могу заставить JSF вызвать сеттер на сущности JPA. Подтверждение JSF завершается с помощью этого сообщения:

form: location: Ошибка проверки: значение недействительно

У меня есть работа над несколькими другими classами того же типа (т. Е. Соединять classы таблиц), но я не могу на всю жизнь заставить этого работать.

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

Используя инструкции журнала, я проверил следующее:

  1. Conveter возвращает правильные, но не null значения.
  2. У меня нет верификации бина в сущности JPA.
  3. setLocation(Location location) никогда не вызывается.

Это самый простой пример, который я могу сделать, и он просто не будет работать:

   

Преобразователь:

 @FacesConverter(forClass=Location.class, value="locationConverter") public class LocationConverter implements Converter, Serializable { private static final Logger logger = Logger.getLogger(LocationConverter.class.getName()); @Override public Object getAsObject(FacesContext context, UIComponent component, String value) { if (value.isEmpty()) return null; try { Long id = Long.parseLong(value); Location location = ((LocationManagedBean) context.getApplication().getELResolver().getValue(context.getELContext(), null, "location")).find(id); logger.log(Level.SEVERE, "Converted {0} to {1}" , new Object[] {value, location}); return location; } catch (NumberFormatException e) { return new Location(); } } @Override public String getAsString(FacesContext context, UIComponent component, Object value) { if (value == null || value.toString().isEmpty() || !(value instanceof Location)) return ""; return String.valueOf(((Location) value).getId()); } } 

Консольный выход:

 // Getter method INFO: Current value=ejb.locations.Location[id=null, name=null, latitude=0.0, longitude=0.0] // Session Bean INFO: Finding ejb.locations.Location with id=3 // Session Bean INFO: ### Returning : ejb.locations.Location[id=3, name=mdmd, latitude=4.5, longitude=2.3] // Converter SEVERE: Converted 3 to ejb.locations.Location[id=3, name=mdmd, latitude=4.5, longitude=2.3] // Getter method -> Where did my selected Location go ?? INFO: Current value=ejb.locations.Location[id=null, name=null, latitude=0.0, longitude=0.0] 

Ошибка проверки с сообщением «form: location: Ошибка проверки: значение недействительно»

Эта ошибка сводится к тому, что выбранный элемент не соответствует ни одному из доступных значений элемента выбора, указанному любым вложенным во время обработки запроса на формы.

В рамках защиты от несанкционированных / взломанных запросов JSF будет повторять все доступные значения элементов выбора и проверять, если selectedItem.equals(availableItem) возвращает true для хотя бы одного доступного значения элемента. Если значение одного элемента не совпадает, вы получите именно эту ошибку проверки.

Этот процесс находится под обложками в основном так, как bean.getAvailableItems() ниже, в соответствии с которым bean.getAvailableItems() представляет собой полный список доступных элементов выбора, как определено :

 String submittedValue = request.getParameter(component.getClientId()); Converter converter = component.getConverter(); Object selectedItem = (converter != null) ? converter.getAsObject(context, component, submittedValue) : submittedValue; boolean valid = false; for (Object availableItem : bean.getAvailableItems()) { if (selectedItem.equals(availableItem)) { valid = true; break; } } if (!valid) { throw new ValidatorException("Validation Error: Value is not valid"); } 

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

  1. Выбранный элемент отсутствует в списке доступных элементов.
  2. Метод equals() classа, представляющего выбранный элемент, отсутствует или сломан.
  3. Если задействован пользовательский Converter , он возвращает неверный объект в getAsObject() . Возможно, это даже null .

Чтобы решить эту проблему:

  1. Убедитесь, что точно такой же список сохранен во время последующего запроса, особенно в случае нескольких каскадных меню. При создании компонента @ViewScoped вместо @RequestScoped следует исправить это в большинстве случаев. Также убедитесь, что вы не выполняете бизнес-логику в методе getter , а вместо этого в @PostConstruct или @PostConstruct события (слушателя). Если вы полагаетесь на конкретные параметры запроса, вам нужно будет явно хранить их в компоненте @ViewScoped или повторно передать их при последующих запросах, например, . См. Также Как выбрать правильную область видимости бобов?
  2. Убедитесь, что метод equals() реализован правильно. Это уже сделано на стандартных Java-типах, таких как java.lang.String , java.lang.Number и т. Д., Но необязательно на пользовательских объектах / beans / entites. См. Также Правильный способ реализации равного контракта . Если вы уже используете String , убедитесь, что кодировка символов запроса настроена правильно. Если он содержит специальные символы, а JSF настроен на рендеринг вывода в виде UTF-8, но интерпретирует ввод, например, ISO-8859-1, то он будет терпеть неудачу. См. Также ao Вход Unicode, полученный через входные компоненты PrimeFaces, поврежден .
  3. Отлаживайте / регистрируйте действия своего настраиваемого Converter и исправляйте его соответствующим образом. Рекомендации см. Также в разделе «Значение ошибки конверсии» для «null Converter». Если вы используете java.util.Date качестве доступных элементов с помощью , убедитесь, что вы не забыли полную часть времени в шаблоне , См. Также «Ошибка проверки: значение недействительно» от f: datetimeConverter .

Смотрите также:

  • Наша вики-страница selectOneMenu
  • Как заполнить параметры h: selectOneMenu из базы данных?
  • Сделайте несколько зависимых / каскадных selectOneMenu выпадающих списков в JSF

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

Просто задайте здесь ясный и конкретный вопрос. Не задавайте слишком широких вопросов;)

В моем случае я забыл реализовать правильные методы get / set. Это произошло потому, что я изменил много атрибутов в процессе разработки.

Без надлежащего метода получения JSF не может восстановить выбранный вами элемент и, как говорит BalusC, в пункте 1 его ответа:

1. Выбранный элемент отсутствует в списке доступных элементов. Это может произойти, если список доступных элементов обслуживается компонентом с включенным запросом, который неправильно повторно инициализируется при последующем запросе или неправильно выполняет деловое задание внутри метода getter, что приводит к тому, что он каким-то образом возвращает другой список.

Это может быть проблема с конвертером или проблема с DTO. Попробуйте решить это, добавив методы hashCode () и equals () в ваш объект DTO; В приведенном выше сценарии вы можете сгенерировать эти методы в classе объекта Location, который указывается здесь как «DTO».

Пример:

 @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + (int) (id ^ (id >>> 32)); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Location other = (Location) obj; if (id != other.id) return false; return true; } 
  • Обратите внимание, что приведенный выше пример относится к «id» типа «long».
  • Как добавить шаблон проверки формы в Angular 2?
  • Как вставить в @FacesValidator с помощью @EJB, @PersistenceContext, @Inject, @Autowired
  • Давайте будем гением компьютера.