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) { }