使用f:setPropertyActionListener的JSF NumberFormatException

时间:2015-05-23 14:30:30

标签: jsf datatable el jsf-2.2 setpropertyactionlistener

我用f:setPropertyActionListener得到了这个错误,我无法找出原因:

HTTP Status 500 - For input string: "selectedItem"

exception:
javax.servlet.ServletException: For input string: "selectedItem"
javax.faces.webapp.FacesServlet.service(FacesServlet.java:667)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)

root cause:
java.lang.NumberFormatException: For input string: "selectedItem"
java.lang.NumberFormatException.forInputString(Unknown Source)
java.lang.Integer.parseInt(Unknown Source)
java.lang.Integer.parseInt(Unknown Source)
javax.el.ListELResolver.coerce(ListELResolver.java:157)
javax.el.ListELResolver.getType(ListELResolver.java:50)
com.sun.faces.el.DemuxCompositeELResolver._getType(DemuxCompositeELResolver.java:215)
com.sun.faces.el.DemuxCompositeELResolver.getType(DemuxCompositeELResolver.java:242)
org.apache.el.parser.AstValue.getType(AstValue.java:60)
org.apache.el.ValueExpressionImpl.getType(ValueExpressionImpl.java:168)
com.sun.faces.facelets.el.TagValueExpression.getType(TagValueExpression.java:98)
com.sun.faces.facelets.tag.jsf.core.SetPropertyActionListenerHandler$SetPropertyListener.processAction(SetPropertyActionListenerHandler.java:209)
javax.faces.event.ActionEvent.processListener(ActionEvent.java:88)
javax.faces.component.UIComponentBase.broadcast(UIComponentBase.java:813)
javax.faces.component.UICommand.broadcast(UICommand.java:300)
javax.faces.component.UIData.broadcast(UIData.java:1108)
javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:790)
javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1282)
com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)
com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198)
javax.faces.webapp.FacesServlet.service(FacesServlet.java:654)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)

表类:

// imports omitted
public class Table<E> extends ArrayList<E> {

    private E selectedItem;

    public E getSelectedItem() { return selectedItem; }

    public void setSelectedItem(E value) { selectedItem = value; }
}

MyTable Bean:

// Imports omitted
@ManagedBean
@ViewScoped
public class MyTable extends Table<File> {

    @PostConstruct
    public void initBean() {
        // Loading some files into the list
    }
}

这是XHTML:

<html> <!-- Namespaces and stuff omitted -->
    <h:head>...</h:head>
    <h:body>
      <h:form>
        <h:dataTable var="item" value="#{myTable}">
          <h:column>
            <h:commandButton value="Try Me!">
              <f:setPropertyActionListener value="#{item}" target="#{myTable.selectedItem}"/>
                <!-- I'm getting a warning from eclipse here: property not found -->
            </h:commandButton>
          </h:column>
        </h:dataTable>
      </h:form>
    </h:body>
</html>

我正在使用Eclipse Luna(Java EE IDE)与Tomcat 8和JSF 2.2.11(mojarra)。任何提示都被接受了,谢谢!

2 个答案:

答案 0 :(得分:1)

你用自己喜欢的bean实现了自己的角色。看看the processing steps for the f:setActionPropertyListener。你的代码在第3步窒息:

  

如果“value”表达式的值不为null,则在“value”和“target”ValueExpressions上调用getType()以确定其属性类型

出于以下原因:

  1. EL处理器已确定myTableList。因此,它已将表达式myTable.selectedItem的评估委托给javax.el.ListELResolver

  2. ELResolver在遇到myTable基础对象时,确定它是List并自动假定以下字符串引用列表索引,即myTable。 selectedItem < / strong>,其中selectedItem应该是列表索引(根据EL规范,[].对于列表是可互换的)。您可以在行动here中看到它。虽然在tomcat源代码中可能不会立即显现,但如果您在Jboss for example中的类似实现中检查注释,则会有以下注释:

      

    如果基础对象是列表,则返回给定索引处的值。 索引由property参数指定,并强制转换为整数

  3. “属性参数”这里指的是表达式的selectedItem部分

    1. EL处理器现在尝试将字符串selectedItem转换为整数(用作列表索引),而整数又在500
    2. 中爆炸

      通过不将数据结构和支持bean(如Rami)结合起来,您可以更轻松地完成工作。 Q建议。这种方式比IMO更清洁

答案 1 :(得分:0)

我的回答应该是一个评论,但它的篇幅太长了,所以我把它写成答案。

我看到一些&#34;错误&#34;在你的代码中:

  1. 所有JSF Beans&amp;对象必须是可序列化的
  2. 如果您使用通用类型,它们应该是Serializable TOO: public class GenericObject<T extends Serializable> implements Serializable {...}

  3. Setter&amp; JSF对象的getter应该像( this.attr = ...; ):
    public void setSelectedItem(E value) { this.selectedItem = value;}

  4. 请确保正确导入managedBean: import javax.faces.bean.ManagedBean;

  5. 而不是<h:dataTable var="item" value="#{myTable}">您应该使用<h:dataTable var="item" value="#{myTable.items}">

    并使用getter和setter将声明为bean的List属性