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


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

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

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

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

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

  1. The 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());
    }    
}
3 68

3 ответа:

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

эта ошибка сводится к тому, что выбранный элемент не соответствует ни одному из доступных значений select item, указанных любым вложенным <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. The equals() метод класса, представляющего выбранный элемент отсутствует или сломан.
  3. если Converter участвует, то он вернул неправильный объект в getAsObject(). Возможно, это даже null.

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

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

Читайте также:


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

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

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

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

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

Это может быть проблема конвертера или проблема 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'.