JSF 2.0 中方法调用的方法签名?

发布于 2024-11-05 13:19:17 字数 8662 浏览 0 评论 0原文

我对从 EL 调用 JSF Bean 时的方法签名有疑问。

在下面的示例中,我有 3 个方法调用,分别在 outputText value 属性和 actionListener && 中。命令按钮的 action 属性。

<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>

    ....

一件奇怪的事情是, actionListener="#{tInputBean.activateDetail(rpbDetail)}"action="#{tInputBean.querySubAnggaranListImpl(rpbDetail.map['subBudget.budget'] )}" 可以使用自定义类型作为参数(在本例中,它是 my.package.Dto 类型):

public void activateDetail(Dto activeDetail) {
    ....
}
public void querySubAnggaranListImpl(Dto budget) {
    DebugUtil.start("querySubAnggaranListImpl");
    ....
    DebugUtil.end("querySubAnggaranListImpl");
}

其中 isNewRecord 方法需要 java.lang.Object :

public boolean isNewRecord(Dto record) { // this does NOT work
    ....
}

这是生成的跟踪:

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 ************

但是如果我添加这个方法,一切顺利:

public boolean isNewRecord(Object o) { // this DOES work
    return isNewRecord((Dto) o);
}

基本问题是这样的: 为什么从 JSF 调用的方法有时可以接受自定义类型,有时则不能?


顺便说一句,我使用的是 tomcat 7,这些是我的依赖项:

<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>

谢谢!

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 !

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

眼眸印温柔 2024-11-12 13:19:17

这是特定于 EL 实现的。从我在一次演示中听到的情况来看,规范对这种情况并不完全清楚,因此实施者必须做出决定。

但 Tomcat 的实现应该如您所期望的那样工作。尝试将您的 tomcat 升级到最新版本,并确保您的 WEB-INF/lib 中没有 EL jar

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文