Поскольку вы говорите о Facelets, я предполагаю, что JSF 2.x.
Для начала, HTML - это одна и вся строка.JSF генерирует HTML.По умолчанию не String
объекты Java преобразуются методом toString()
в их представление String
, в то время как JSF генерирует HTML.Для правильного преобразования между этими объектами Java и String
вам необходим Converter
.
Я предполагаю, что ваш Country
объект уже имеет equals()
метод правильнореализован , в противном случае проверка позже завершится неудачно с «Ошибка проверки: значение недопустимо», поскольку выбранный объект не возвращает true
при проверке equals()
для любого из доступных элементов.
IЯ также внесу небольшое изменение в именование, поскольку #{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
.