F:selectItems показывает класс не значение

Я новичок в Facelets, и я создал проект с использованием NetBeans, но я боролся с тегом.

я имею

<h:selectOneMenu id="country" value="#{organisation.organisation.country}" title="Country" >
                <f:selectItems value="#{country.countryItemsAvailableSelectOne}"/>
            </h:selectOneMenu>

В выбранном я получаю classpath.Country[iso=GB], который я вижу, это объект, но я действительно хочу увидеть значение country.prinableName. Я смотрел на это в течение полдня и нарисовал пустой Спасибо за любую помощь

3 ответа

Поскольку вы говорите о Facelets, я предполагаю, что JSF 2.x.

Для начала, HTML - это одна и все строка. JSF генерирует HTML. По умолчанию String Java объекты toString() метод преобразован в их String представление в то время как JSF генерирует HTML. Чтобы правильно конвертировать между этими объектами Java и String, тебе необходимо Converter,

Я полагаю, что ваш Country объект уже equals() метод реализован правильно, в противном случае валидация завершится с ошибкой "Ошибка валидации: значение недействительно", потому что выбранный объект не возвращает true на тестировании equals() для любого из доступных предметов.

Я также сделаю небольшое изменение в именовании, так как #{country} это запутанное имя управляемого бина, потому что оно, очевидно, не представляет экземпляр Country учебный класс. Я позвоню Data который должен хранить данные приложения.

@ManagedBean
@ApplicaitionScoped
public class Data {

    private static final List<Country> COUNTRIES = populateItSomehow();

    public List<Country> getCountries() {
        return COUNTRIES;
    }

    // ...
}

Я предполагаю, что Country класс имеет два свойства code а также name, Я предполагаю, что управляемый компонент, который получает выбранную страну, имеет private Country country имущество. В вашем <f:selectItems> нужно перебрать #{data.countries} и укажите объект страны в качестве значения элемента и название страны в качестве метки элемента.

<h:selectOneMenu value="#{bean.country}">
    <f:selectItems value="#{data.countries}" var="country" itemValue="#{country}" itemLabel="#{country.name}" />
</h:selectOneMenu>

Теперь вам нужно создать Converter для Country учебный класс. Мы будем конвертировать на основе кода страны, который уникален для каждой страны (верно?). в getAsString() Вы реализуете код, который преобразует объект Java в его уникальное строковое представление, которое должно использоваться в HTML. В getAsObject() Вы реализуете код, который преобразует уникальное представление HTML String обратно в объект Java.

@FacesConverter(forClass=Country.class)
public class CountryConverter implements Converter {

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object value) {
        return (value instanceof Country) ? ((Country) value).getCode() : null;
    }

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value) {
        if (value == null) {
            return null;
        }

        Data data = context.getApplication().evaluateExpressionGet(context, "#{data}", Data.class);

        for (Country country : data.getCountries()) {
            if (country.getCode().equals(value)) {
                return country;
            }
        }

        throw new ConverterException(new FacesMessage(String.format("Cannot convert %s to Country", value)));
    }

}

@FacesConverter зарегистрирует его автоматически в JSF, и JSF будет автоматически использовать его всякий раз, когда он встречает выражение значения Country тип. В конечном итоге вы получаете код страны в качестве значения элемента и название страны в качестве метки элемента. JSF преобразует представленный код страны обратно в полноценный Country объект при отправке формы.

В JSF 1.x принцип не сильно отличается. В этом блоге вы можете найти два основных примера: Объекты в h:selectOneMenu,

Что с тобой случилось, selectOneMenu позвонить toString() метод для всех заданных объектов.

Вы должны использовать selectitems или простой converter управлять этим. Очень простой пример:

price.xhtml:

<h:selectOneMenu id="priceMenu" value="#{priceBean.selectedPrice}">
    <f:selectItems value="#{priceBean.prices}" />
</h:selectOneMenu>

PriceBean.java:

..
private String selectedPrice;
..
public String getSelectedPrice() {
    return selectedPrice;
}

public void setSelectedPrice(String newPrice) {
    selectedPrice = newPrice;
}
..
public List<SelectItem> getPrices() {
    List<SelectItem> retVal = new ArrayList<SelectItem>();

    retVal.add(new SelectItem("2"));
    retVal.add(new SelectItem("4"));
    retVal.add(new SelectItem("6"));

    return retVal;
}

Дополнительная информация о SelectItem, Если вы хотите использовать специальный объект напрямую, например, объект с именем Price, вы должны использовать конвертер. Здесь показан пример и здесь.

Если вы добавите editable="true" в вашем

<h:selectOneMenu value="#{bean.country}">

Тогда вы получите неожиданный String значение (не из getAsString()) в методе конвертера:

public Object getAsObject(FacesContext context, UIComponent component, String value) { }
Другие вопросы по тегам