Ошибка проверки: значение недействительно - PullRequest
73 голосов
/ 30 января 2012

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

форма: местоположение: Ошибка проверки: значение недопустимо

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

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

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

  1. Conveter возвращает правильные значения, отличные от null.
  2. У меня нет проверки бинов в сущностях JPA.
  3. Сеттер 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] 

Ответы [ 3 ]

129 голосов
/ 30 января 2012

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

Эта ошибка сводится к тому, что выбранный элемент несопоставить любое из доступных значений элемента выбора, указанных любым вложенным тегом <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");
}

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

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

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

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

См. Также:


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

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

2 голосов
/ 12 февраля 2015

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

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

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

1 голос
/ 16 августа 2018

Это может быть проблема с конвертером или проблема с DTO. Попробуйте решить эту проблему, добавив методы hashCode () и equals () в ваш объект DTO; В приведенном выше сценарии вы можете сгенерировать эти методы в классе объекта 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.
...