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
是不必要的、无意义的。