F:selectItems显示类不是值

use*_*854 2 jsf

我是facelets的新手,我使用netbeans生成了一个项目但是我在使用标签时遇到了困难.

我有

<h:selectOneMenu id="country" value="#{organisation.organisation.country}" title="Country" >
                <f:selectItems value="#{country.countryItemsAvailableSelectOne}"/>
            </h:selectOneMenu>
Run Code Online (Sandbox Code Playgroud)

在select I get classpath.Country [iso = GB]我可以看到它是一个对象,但我真的想看到country.prinableName值.我已经看了半天,并且已经画了一个空白谢谢你的帮助

Bal*_*usC 7

既然你在谈论Facelets,我会假设JSF 2.x.

首先,HTML是一个和所有String.JSF生成HTML.默认情况下,非StringJS对象通过toString()方法转换为其String表示形式,而JSF生成HTML.要在这些Java对象之间正确转换String,您需要一个Converter.

我假设您的Country对象已经正确实现了该equals()方法,否则验证将在稍后失败并显示"验证错误:值无效",因为所选对象在测试任何可用项时都不会返回.trueequals()

我还会对命名做一点改动,#{country}因为它是一个令人困惑的托管bean名称,因为它显然不代表Country类的实例.我将其称为Data应该保存应用程序范围的数据.

@ManagedBean
@ApplicaitionScoped
public class Data {

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

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

    // ...
}
Run Code Online (Sandbox Code Playgroud)

我假设Country该类有两个属性codename.我假设接收所选国家/地区的托管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>
Run Code Online (Sandbox Code Playgroud)

现在,您需要ConverterCountry类创建一个.我们将根据每个国家/地区唯一的国家/地区代码进行转换(对吗?).在getAsString()您实现代码中,该代码将Java对象转换为将在HTML中使用的唯一String表示形式.在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)));
    }

}
Run Code Online (Sandbox Code Playgroud)

@FacesConverter将在JSF自动注册它,每当它遇到的值表达式JSF会自动将其Country类型.最终,您最终将国家/地区代码作为项目值,将国家/地区名称作为项目标签.在提交Country表单时,JSF会将提交的国家/地区代码转换回完整的对象.

在JSF 1.x中,原则并没有太大的不同.在这篇博客中,您可以找到两个基本启动示例:对象h:selectOneMenu.