Facelet selectOneMenu с POJO и проблемой конвертера - PullRequest
1 голос
/ 23 марта 2010

Я хочу иметь страницу с лицевым щитком с формулой и выпадающим меню. В раскрывающемся меню пользователь должен выбрать POJO типа Lieferant:

public class Lieferant extends AbstractPersistentWarenwirtschaftsObject {

    private String firma;

    public Lieferant(WarenwirtschaftDatabaseLayer database, String firma) {
        this(database, null, firma);
    }

    public Lieferant(WarenwirtschaftDatabaseLayer database, Long primaryKey, String firma) {
        super(database, primaryKey);
        this.firma = firma;
    }

    public String getFirma() {
        return firma;
    }

    @Override
    public String toString() {
        return getFirma();
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((firma == null) ? 0 : firma.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Lieferant other = (Lieferant) obj;
        if (firma == null) {
            if (other.firma != null)
                return false;
        } else if (!firma.equals(other.firma))
            return false;
        return true;
    }

}

Вот код лица, который я написал:

<h:selectOneMenu> 

бирка. Этот тег должен отображать список POJO (не бинов) типа Lieferant. Вот код лица:

<h:selectOneMenu id="lieferant" value="#{lieferantenBestellungBackingBean.lieferant}">
 <f:selectItems var="lieferant" value="#{lieferantenBackingBean.lieferanten}" itemLabel="#{lieferant.firma}" itemValue="#{lieferant.primaryKey}" />
 <f:converter converterId="LieferantConverter" />
</h:selectOneMenu>

Вот управляемый компонент EJB

@ManagedBean
@RequestScoped
public class LieferantenBackingBean extends AbstractWarenwirtschaftsBackingBean {

    private List<Lieferant> lieferanten;

    public List<Lieferant> getLieferanten() {
        if (lieferanten == null) {
            lieferanten = getApplication().getLieferanten();
        }
        return lieferanten;
    }

}

Насколько я знаю, мне нужен специальный конвертер, чтобы поменять местами представления POJO и String объектов Lieferant. Вот как выглядит конвертер:

@FacesConverter(value="LieferantConverter")
public class LieferantConverter implements Converter {

 @Override
 public Object getAsObject(FacesContext context, UIComponent component, String value) {
  long primaryKey = Long.parseLong(value);
  WarenwirtschaftApplicationLayer application = WarenwirtschaftApplication.getInstance();
  Lieferant lieferant = application.getLieferant(primaryKey);
  return lieferant;
 }

 @Override
 public String getAsString(FacesContext context, UIComponent component, Object value) {
  return value.toString();
 }

}

Страница загружается без ошибок. Когда я заполняю формуляр и отправляю его, на странице появляется сообщение об ошибке:

Bestellung:lieferantenBestellungForm:lieferant: Validierungsfehler: Wert ist keine gültige Auswahl
translated: validation error: value is not a valid selection

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

Я нашел этот похожий вопрос из stackoverflow и этот статья о selectOneMenu и конвертерах , но мне не удалось найти проблему в моем коде. Почему

List<SelectItem> 

используется в примере со второй ссылки. Выдает ту же ошибку для меня.

Любая помощь будет оценена. Заранее спасибо.

Ответы [ 2 ]

2 голосов
/ 23 марта 2010

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

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

Чтобы исключить одно или другое: вы можете легко протестировать Object#equals() с помощью "простого ванильного" теста и вы можете проверить согласованность списка, поместив компонент в область действия сеанса.

Для ясности, ваш конвертер выглядит нормально и, кажется, работает нормально (иначе вы бы не смогли получить такого рода сообщение об ошибке; таким образом, шаг конвертации был успешно завершен).

0 голосов
/ 23 марта 2010

Я был действительно уверен, что конвертер работал правильно, но последняя ошибка была в конвертере. Может быть, это произошло в течение нескольких часов отладки. Вот фиксированный метод getAsString конвертера. N

@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
    if (value != null && value instanceof Lieferant) {
        Lieferant lieferant = (Lieferant) value;
        return "" + lieferant.getPrimaryKey();
    }
    return "";
}

Теперь он возвращает primaryKey, который используется в качестве значения списка selectOneMenu. Дополнительно я изменил этот атрибут из тега selectItems:

 itemValue="#{lieferant}"

Сейчас я не уверен, было ли это последнее изменение необходимым. Но теперь обманщики обратились правильно.

...