Ответ 1
Поскольку вы говорите о Facelets, я буду считать JSF 2.x.
Для начала HTML - это одна и вся строка. JSF генерирует HTML. По умолчанию объекты String
Java не соответствуют String
методом toString()
, преобразованным в их представление String
, в то время как JSF генерирует HTML. Чтобы правильно преобразовать эти объекты Java и String
, вам понадобится Converter
.
Я предполагаю, что ваш объект Country
уже имеет метод equals()
правильно реализован, иначе проверка позже завершится с ошибкой проверки: значение недействительно, потому что выбранный объект не возвращает true
при тестировании equals()
для любого из доступных элементов.
Я также сделаю небольшое изменение в названии, так как #{country}
является запутанным управляемым именем bean, потому что он, по-видимому, не представляет экземпляр класса Country
. Я назову его Data
, который должен содержать данные расширенного приложения.
@ManagedBean
@ApplicaitionScoped
public class Data {
private static final List<Country> COUNTRIES = populateItSomehow();
public List<Country> getCountries() {
return COUNTRIES;
}
// ...
}
Я предполагаю, что класс Country
имеет два свойства code
и name
. Я предполагаю, что управляемый bean, который получает выбранную страну, имеет свойство 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
.