在表的一列中,我试图将组件值绑定到本地范围的EL变量,然后将该变量用作参数:
<h:column>
<h:outputLabel value="Enter a quantity to put into the cart" for="qty"/>
<h:inputText id="qty" binding="#{qty}" converter="javax.faces.Number"/>
</h:column>
<h:column>
<h:commandButton value="Put into cart" type="submit"
action="#{shoppingCart.addToCart(product, qty)}"/>
</h:column>
其中product
是数据表的当前元素(不在购物车中的已过滤或未过滤产品的列表)。
现在,当尝试将产品添加到购物车时(例如数量为12),它会抛出以下异常:
javax.faces.el.EvaluationException: java.lang.IllegalArgumentException: Cannot convert javax.faces.component.html.HtmlInputText@377c8b02 of type class javax.faces.component.html.HtmlInputText to class java.lang.Integer
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:101)
at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
at javax.faces.component.UICommand.broadcast(UICommand.java:315)
at javax.faces.component.UIData.broadcast(UIData.java:1108)
at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:790)
at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1282)
at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:658)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:318)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:416)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:283)
at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:459)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:167)
at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:206)
at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:180)
at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:235)
at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:283)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:200)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:132)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:111)
at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:536)
at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:591)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:571)
at java.lang.Thread.run(Thread.java:745)
我正在使用Glassfish 4.1.1和JSF 2.2.12版。
我很感激任何想法
CLARIFACATION
正如BalusC在这个问题JSF component binding without bean property及其他人中指出的,binding="#{var}"
实际上是有效的XHTML。这样就不需要支持bean,声明的变量是请求作用域。我发现这个选项更优雅,因此我想坚持下去。
答案 0 :(得分:1)
使用:binding="#{qty}"
,或者如果您正在处理列表,而不是value="#{shoppingCart.quantityAsInteger}"
(应该用于将输入组件绑定到托管bean中组件的Java实例)。购物车项目:value="#{shoppingCartItem.quantityAsInteger}"
。
除了正确的价值绑定之外,这还可以让您将数量作为模型的一部分。此外,当value
绑定到Integer
时,无需添加转换器。 JSF将负责Integer
(and some other types) conversion by default。
因此,请确保您拥有一个托管bean,其中包含数量或购物车商品列表,每个商品都有数量。如果是购物车商品清单,您最终会得到以下内容:
<强> ShoppingCart.java 强>
// You will probably already have something like this for your table
private List<ShoppingCartItem> shoppingCartItems;
<强> ShoppingCartItem.java 强>
// Quantity used for binding (add getter and setter).
private Integer quantity;
private Product product;
<强> XHTML 强>
<h:column>
<h:outputLabel value="Enter a quantity to put into the cart" for="qty"/>
<h:inputText id="qty" binding="#{shoppingCartItem.quantity}" />
</h:column>
答案 1 :(得分:0)
尝试在value
中使用binding
属性而不是h:inputText
属性,并在表格组件上使用binding
属性。这样您就可以访问操作方法中的所选(单击)行:如果表的binding
属性值为#{bean.dataTable}
,则可以使用getDataTable.getRowData()
等方法获取行数据。
答案 2 :(得分:0)
虽然声明EL变量是有效的XHTML,但如果使用binding
属性,则组件本身会绑定到变量。将EL变量与value
属性一起使用时,不会引发转换错误,如:
<h:inputText id="qty" value="#{qty}" converter="javax.faces.Number"/>
....
<h:commandButton value="Put into cart" type="submit"
action="#{shoppingCart.addToCart(product, qty)}"/>