Method signature for method calling in JSF 2.0?
I have a question about the method signature in a JSF Bean when it's invoked from an EL.
In the example below, i have 3 method calls, in the outputText value
attribute, and in the actionListener
&& action
attribute for the command Button.
<p:dataTable id="gridRPBDetails"
var="rpbDetail"
value="#{tInputBean.detailList}"
selection="#{tInputBean.selectedDetails}">
....
<p:column selectionMode="multiple" />
<p:column>
<h:outputText value="#{tInputBean.isNewRecord(rpbDetail) ? 'New' : tInputBean.isEditRecord(rpbDetail) ? 'Edited' : '-'}"/>
</p:column>
<p:column>
<p:commandButton
process="@this"
actionListener="#{tInputBean.activateDetail(rpbDetail)}"
action="#{tInputBean.querySubAnggaranListImpl(rpbDetail.map['subBudget.budget'])}"
update="DetailDialogForm"
oncomplete="detailDialog.show();"
image="ui-icon ui-icon-search"/>
</p:column>
....
One strange thing is that, both actionListener="#{tInputBean.activateDetail(rpbDetail)}"
and action="#{tInputBean.querySubAnggaranListImpl(rpbDetail.map['subBudget.budget'])}"
can have a custom type as the parameter (in this case, it's a my.package.Dto type) :
public void activateDetail(Dto activeDetail) {
....
}
public void querySubAnggaranListImpl(Dto budget) {
DebugUtil.start("querySubAnggaranListImpl");
....
DebugUtil.end("querySubAnggaranListImpl");
}
where the isNewRecord method expects a java.lang.Object :
public boolean isNewRecord(Dto record) { // this does NOT work
....
}
This is the generated traces :
ERROR BusinessExceptionHandler - javax.el.ELException: /TInput.xhtml @156,130 value="#{tInputBean.isNewRecord(rpbDetail) ? 'New' : tInputBean.isEditRecord(rpbDetail) ? 'Edited' : '-'}": java.lang.NoSuchMethodException: id.co.sofcograha.cashbank.webapp.paymentplan.TInputBean.isNewRecord(java.lang.Object)
javax.el.ELException: /TInput.xhtml @156,130 value="#{tInputBean.isNewRecord(rpbDetail) ? 'New' : tInputBean.isEditRecord(rpbDetail) ? 'Edited' : '-'}": java.lang.NoSuchMethodException: id.co.sofcograha.cashbank.webapp.paymentplan.TInputBean.isNewRecord(java.lang.Object)
at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:114)
at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:193)
at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:181)
at javax.faces.component.UIOutput.getValue(UIOutput.java:169)
at com.sun.faces.renderkit.html_basic.HtmlBasicInputRenderer.getValue(HtmlBasicInputRenderer.java:205)
at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.getCurrentValue(HtmlBasicRenderer.java:355)
at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeEnd(HtmlBasicRenderer.java:164)
at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:883)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1659)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1655)
at org.primefaces.component.datatable.DataTableRenderer.encodeRegularCell(DataTableRenderer.java:571)
at org.primefaces.component.datatable.DataTableRenderer.encodeRow(DataTableRenderer.java:531)
at org.primefaces.component.datatable.DataTableRenderer.encodeTbody(DataTableRenderer.java:472)
at org.primefaces.component.datatable.DataTableRenderer.encodeRegularTable(DataTableRenderer.java:201)
at org.primefaces.component.datatable.DataTableRenderer.encodeMarkup(DataTableRenderer.java:180)
at org.primefaces.component.datatable.DataTableRenderer.encodeEnd(DataTableRenderer.java:85)
at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:883)
at org.primefaces.renderkit.CoreRenderer.renderChild(CoreRenderer.java:59)
at org.primefaces.renderkit.CoreRenderer.renderChildren(CoreRenderer.java:43)
at org.primefaces.component.panel.PanelRenderer.encodeContent(PanelRenderer.java:229)
at org.primefaces.component.panel.PanelRenderer.encodeMarkup(PanelRenderer.java:152)
at org.primefaces.component.panel.PanelRenderer.encodeEnd(PanelRenderer.java:75)
at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:883)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1659)
at javax.faces.render.Renderer.encodeChildren(Renderer.java:168)
at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:853)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1652)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1655)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1655)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1655)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1655)
at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:399)
at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:131)
at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:121)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:313)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:306)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161)
at org.apache.catalina开发者_如何学编程.core.StandardHostValve.invoke(StandardHostValve.java:164)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:541)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:383)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:243)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:188)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:166)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:288)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
Caused by: java.lang.NoSuchMethodException: id.co.sofcograha.cashbank.webapp.paymentplan.TInputBean.isNewRecord(java.lang.Object)
at java.lang.Class.getMethod(Class.java:1605)
at javax.el.BeanELResolver.invoke(BeanELResolver.java:405)
at javax.el.CompositeELResolver.invoke(CompositeELResolver.java:161)
at org.apache.el.parser.AstValue.getValue(AstValue.java:159)
at org.apache.el.parser.AstChoice.getValue(AstChoice.java:45)
at org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:189)
at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:109)
... 52 more
DEBUG DebugUtil - ************ END printing stack trace ************
But if i add this method, everything works smoothly :
public boolean isNewRecord(Object o) { // this DOES work
return isNewRecord((Dto) o);
}
The basic question is this : Why is it that method calling from JSF can sometimes accept a custom type, and sometimes not ?
By the way, im using tomcat 7, and these are my dependencies :
<dependency>
<groupId>org.primefaces</groupId>
<artifactId>primefaces</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>com.sun.faces</groupId>
<artifactId>jsf-api</artifactId>
<version>2.0.4-b09</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.sun.faces</groupId>
<artifactId>jsf-impl</artifactId>
<version>2.0.4-b09</version>
<scope>compile</scope>
</dependency>
Thank you !
This is specific to the EL implementation. From what I heard on one presentation, the spec is not completely clear about such situations, so implementors have to decide.
But Tomcat's implementation should work as you expect. Try upgrading your tomcat to the latest release and make sure you don't have an EL jar in your WEB-INF/lib
精彩评论