Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/336.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JSF2.0转换器是否需要SelectItems?_Java_Jsf 2_Converter_Selectonemenu - Fatal编程技术网

Java JSF2.0转换器是否需要SelectItems?

Java JSF2.0转换器是否需要SelectItems?,java,jsf-2,converter,selectonemenu,Java,Jsf 2,Converter,Selectonemenu,我得到以下信息: 值不是字符串(class=org.xxx.Foo,Value=org.xxx)。Foo@366d5595)组件j_id17:j_id114:j_id125,路径:{组件路径:[Class:org.ajax4jsf.framework.ajax.AjaxViewRoot,ViewId:/foo.xhtml][Class:org.ajax4jsf.ajax.html.Include,Id:j_id17][Class:javax.faces.component.html.HtmlFo

我得到以下信息:

值不是字符串(class=org.xxx.Foo,Value=org.xxx)。Foo@366d5595)组件j_id17:j_id114:j_id125,路径:{组件路径:[Class:org.ajax4jsf.framework.ajax.AjaxViewRoot,ViewId:/foo.xhtml][Class:org.ajax4jsf.ajax.html.Include,Id:j_id17][Class:javax.faces.component.html.HtmlForm,Id:j_id114][Class:javax.faces.component.html.HtmlSelectOneMenu,Id:j_id125]}没有转换器。

Xhtml:


富是:

import javax.faces.model.SelectItem;
@Audited
@Entity
@Table(name= "foo")
@AccessType("property")
public class Foo extends SelectItem implements Serializable{
     ....
}

为什么我需要一个转换器来从SelectItem转换到SelectItem?

当JSF在显示期间尝试从
Foo
中收集所选值,以及在回发期间尝试从所选值返回
Foo
时,就会出现问题。正如BalusC提到的,扩展
SelectItem
不是一个好方法。您可以ave两个常规选项之一:手动处理选择或使用转换器

转换器非常适合适应几乎任何类型的对象,这样就可以通过UI元素直接引用和显示它们。不幸的是,当转换不简单时,转换器可能需要额外的步骤

我注意到了
@Entity
注释,因此我假设您试图显示一个记录列表,用户可以从中进行选择。90%的情况下,这些选择是为了获取记录的主键,而不是记录本身,以便在后续查询或业务逻辑中使用。对于这种情况,手动选择n更有效。但是,如果您还需要获取记录内容,那么转换器更适合,因为它将处理查找逻辑,并让您的业务逻辑直接处理记录

我不打算指定您应该选择哪种方法,但由于您最初的问题集中在手动方法上,因此我将提供此解决方案

public class Foo {
    private long id;
    private String label;

    public Foo( long id, String label ) {
        this.id = id;
        this.label = label;
    }

    public long getId() {
        return id;
    }

    public void setId( long id ) {
        this.id = id;
    }

    public String getLabel() {
        return label;
    }

    public void setLabel( String label ) {
        this.label = label;
    }
}
下面给出的一个简单的
FooCntrl
bean将提供演示信息并处理选择的回发

@Named
@ViewScoped
public class FooCntrl implements Serializable {
private long selected = 0;

    // Stub for what an EntityManager would normally provide.
    public List<Foo> getRecords () {
        List<Foo> fooList = new ArrayList<Foo>();
        fooList.add( new Foo( 11, "Paul" ) );
        fooList.add( new Foo( 23, "John" ) );
        fooList.add( new Foo( 32, "George" ) );
        fooList.add( new Foo( 47, "Ringo" ) );
        return fooList;
    }

    public long getSelected() {
        return selected;
    }

    public void setSelected( long selected ) {
        this.selected = selected;
        System.out.println( "You picked record id: " + selected );
    }

    public List<Foo> getFooList() {
        return getRecords();
    }
}
@Named
@视域
公共类FooCntrl实现可序列化{
私人长选中=0;
//实体管理器通常提供的存根。
公共列表记录(){
列表列表=新的ArrayList();
添加(新富(11,“保罗”);
加上(新富(23,“约翰”);
添加(新富(32,“乔治”);
添加(新富(47,“林戈”);
回归愚人;
}
公共长getSelected(){
返回选中的;
}
已选择的公共资源(长选){
this.selected=selected;
System.out.println(“您选择的记录id:+selected”);
}
公共列表get傻瓜列表(){
返回getRecords();
}
}
这反过来会驱动UI选择菜单

...
<h:form>
    <h:selectOneMenu value="#{fooCntrl.selected}">
        <f:selectItem itemValue="0" itemLabel="Select One..." />
        <f:selectItems value="#{fooCntrl.fooList}" var="r" itemLabel="#{r.label}" itemValue="#{r.id}"/>
    </h:selectOneMenu>
    <h:commandButton value="Submit" />
</h:form>
...
。。。
...

这只是一个变体。我肯定有些人会不同意它,并一直推荐转换器,甚至推荐另一种手动方法。我的目标是为您提供一些可以向前推进的东西。我将让您按照自己的速度改进设计方法和样式:)。

因为HTML和HTTP无法在您的周围传递nd Java对象。它们只能传递由
字符串
表示的Java字符。
转换器
可以在该
字符串
和所需Java对象之间进行转换。顺便说一句,
扩展SelectItem
是不必要的、无意义的。