f:setPropertyActionListener 的 JSF NumberFormatException
JSF NumberFormatException with f: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)
Table Class:
// imports omitted
public class Table<E> extends ArrayList<E> {
private E selectedItem;
public E getSelectedItem() { return selectedItem; }
public void setSelectedItem(E value) { selectedItem = value; }
}
我的Table豆子:
// 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) 一起使用。接受任何提示,谢谢!
我的答案应该是评论,但它太长了,所以我把它写成答案。
我在你的代码中看到一些 "ERRORS":
- 所有 JSF Bean 和对象都必须是可序列化的
如果您使用通用类型,它们也应该是可序列化的:
public class GenericObject<T extends Serializable> implements Serializable {...}
JSF 对象的 Setter & Getter 应该像 (this.attr = ...;) :
public void setSelectedItem(E value) { this.selectedItem = value;}
确保您正确导入了 managedBean:
import javax.faces.bean.ManagedBean;
而不是 <h:dataTable var="item" value="#{myTable}">
你应该使用 <h:dataTable var="item" value="#{myTable.items}">
并使用 getter 和 setter
将 items 声明为您的 bean 的列表属性
您使用花哨的 bean 实现将自己编码到了一个角落。看看 the processing steps for the f:setActionPropertyListener
。您的代码在第 3 步阻塞:
If the value of the "value" expression is not null, call getType() on the "value" and "target" ValueExpressions to determine their property types
原因如下:
EL 处理器已确定 myTable
是 List
。因此,它已将表达式 myTable.selectedItem
的计算委托给 javax.el.ListELResolver
class
ELResolver 在遇到 myTable
基础对象时,确定它是一个 List
并自动假定以下字符串引用列表索引,即 myTable。selectedItem,其中 selectedItem
应该是列表索引(根据 EL 规范,[]
和 .
对于列表是可互换的)。您可以看到它的实际效果 here. While it may not be immediately apparent in the tomcat source, if you check the comment in a similar implementation in Jboss for example,您有以下评论:
If the base object is a list, returns the value at the given index. The index is specified by the property argument, and coerced into an integer
"属性 参数" 这里指的是你表达式的 selectedItem
部分
- EL 处理器现在尝试将字符串
selectedItem
转换为整数(用作列表索引),然后在 500
中展开
通过不将数据结构和辅助 bean 结合起来(如 Rami),您的工作将变得更加轻松。问建议。 IMO
这样更干净
我在使用 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)
Table Class:
// imports omitted
public class Table<E> extends ArrayList<E> {
private E selectedItem;
public E getSelectedItem() { return selectedItem; }
public void setSelectedItem(E value) { selectedItem = value; }
}
我的Table豆子:
// 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) 一起使用。接受任何提示,谢谢!
我的答案应该是评论,但它太长了,所以我把它写成答案。
我在你的代码中看到一些 "ERRORS":
- 所有 JSF Bean 和对象都必须是可序列化的
如果您使用通用类型,它们也应该是可序列化的:
public class GenericObject<T extends Serializable> implements Serializable {...}
JSF 对象的 Setter & Getter 应该像 (this.attr = ...;) :
public void setSelectedItem(E value) { this.selectedItem = value;}
确保您正确导入了 managedBean:
import javax.faces.bean.ManagedBean;
而不是
<h:dataTable var="item" value="#{myTable}">
你应该使用<h:dataTable var="item" value="#{myTable.items}">
并使用 getter 和 setter
将 items 声明为您的 bean 的列表属性
您使用花哨的 bean 实现将自己编码到了一个角落。看看 the processing steps for the f:setActionPropertyListener
。您的代码在第 3 步阻塞:
If the value of the "value" expression is not null, call getType() on the "value" and "target" ValueExpressions to determine their property types
原因如下:
EL 处理器已确定
myTable
是List
。因此,它已将表达式myTable.selectedItem
的计算委托给javax.el.ListELResolver
classELResolver 在遇到
myTable
基础对象时,确定它是一个List
并自动假定以下字符串引用列表索引,即 myTable。selectedItem,其中selectedItem
应该是列表索引(根据 EL 规范,[]
和.
对于列表是可互换的)。您可以看到它的实际效果 here. While it may not be immediately apparent in the tomcat source, if you check the comment in a similar implementation in Jboss for example,您有以下评论:If the base object is a list, returns the value at the given index. The index is specified by the property argument, and coerced into an integer
"属性 参数" 这里指的是你表达式的 selectedItem
部分
- EL 处理器现在尝试将字符串
selectedItem
转换为整数(用作列表索引),然后在500
中展开
通过不将数据结构和辅助 bean 结合起来(如 Rami),您的工作将变得更加轻松。问建议。 IMO
这样更干净