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

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

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

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

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

С помощью операторов журнала я проверил следующее:

  • Conveter возвращает правильные значения не null.
  • У меня нет Bean Проверка в моих сущностях JPA.
  • Отправитель setLocation(Location location) никогда не вызывается.

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

<h:body>
    <h:form id="form">
        <p:messages id="messages" autoUpdate="true" />
        <p:selectOneMenu id="location" value="#{locationStockList.selected.location}" converter="locationConverter">
            <p:ajax event="change" update=":form:lblLocation"/>
            <f:selectItems value="#{locationStockList.locationSelection}"/>
        </p:selectOneMenu>
    </h:form>
</h:body>

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

@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] 

Ответы

Ответ 1

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

Эта ошибка сводится к тому, что выбранный элемент не соответствует ни одному из доступных значений элемента выбора, указанному любым вложенным тегом <f:selectItem(s)> во время обработки запроса на отправку формы.

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

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

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");
}

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

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

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

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

См. также:


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

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

Ответ 2

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

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

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