由於您在談論Facelets,我將假設JSF 2.x.
首先,HTML是一個和所有的字符串。 JSF生成HTML。默認情況下,當JSF生成HTML時,非String
Java對象被toString()
方法轉換爲其String
表示。要正確地在這些Java對象和String
之間進行轉換,您需要一個Converter
。
我假設你Country
對象已具有equals()
方法properly implemented,否則驗證稍後將會失敗「驗證錯誤:值無效」,因爲所選擇的對象不針對任何可用項目的測試equals()
返回true
。
因爲#{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>
現在,你需要爲Country
類創建Converter
。我們將根據每個國家/地區獨有的國家代碼進行轉換(對嗎?)。在getAsString()
中,實現了將Java對象轉換爲在HTML中使用的唯一字符串表示形式的代碼。在getAsObject()
中,實現了將唯一HTML字符串表示轉換回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自動註冊它,每當它遇到的Country
類型的值表達JSF將自動使用它。最終,你最終將國家代碼作爲項目價值和國家名稱作爲項目標籤。在提交表單時,JSF將把提交的國家代碼轉換回完整的Country
對象。
在JSF 1.x中,原理沒有多大區別。在這個博客中,您可以找到兩個基本的開球示例:Objects in h:selectOneMenu
。
謝謝你所有的假設是否正確和很好的解釋將通過這個例子起作用,它也會幫助我 – user845854