注释掉的 Facelets 代码仍然调用 #{bean.action()} 等 EL 表达式,并导致 #{bean.action} 上出现 javax.el.PropertyNotFoundException

问题描述 投票:0回答:3

我的 Facelet 中有以下代码片段:

<h:commandLink id="cmdbtn">
    <f:ajax event="click" execute="@form"
            listener="#{screenShotBean.takeScreenshot}" />
</h:commandLink>

它工作得很好,但是当我像这样评论它时,

<!--        <h:commandLink id="cmdbtn"> -->
<!--            <f:ajax event="click" execute="@form" -->
<!--                    listener="#{screenShotBean.takeScreenshot}" /> -->
<!--        </h:commandLink> -->

然后抛出以下异常:

javax.el.PropertyNotFoundException: Property 'takeScreenshot' not found on type monstage.test.com.ScreenShotBean
    at javax.el.BeanELResolver$BeanProperties.get(BeanELResolver.java:237)
    at javax.el.BeanELResolver$BeanProperties.access$400(BeanELResolver.java:214)
    at javax.el.BeanELResolver.property(BeanELResolver.java:325)
    at javax.el.BeanELResolver.getValue(BeanELResolver.java:85)
    at com.sun.faces.el.DemuxCompositeELResolver._getValue(DemuxCompositeELResolver.java:176)
    at com.sun.faces.el.DemuxCompositeELResolver.getValue(DemuxCompositeELResolver.java:203)
    at org.apache.el.parser.AstValue.getValue(AstValue.java:169)
    at org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:189)
    at com.sun.faces.facelets.el.ELText$ELTextVariable.toString(ELText.java:217)
    at com.sun.faces.facelets.el.ELText$ELTextComposite.toString(ELText.java:157)
    at com.sun.faces.facelets.compiler.CommentInstruction.write(CommentInstruction.java:77)
    at com.sun.faces.facelets.compiler.UIInstructions.encodeBegin(UIInstructions.java:82)
    at com.sun.faces.facelets.compiler.UILeaf.encodeAll(UILeaf.java:183)
    at javax.faces.render.Renderer.encodeChildren(Renderer.java:168)
    at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:845)
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1779)
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1782)
    at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:424)
    at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:125)
    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:594)

当我如下更改带括号的方法表达式时,

<!--        <h:commandLink id="cmdbtn"> -->
<!--            <f:ajax event="click" execute="@form" -->
<!--                    listener="#{screenShotBean.takeScreenshot()}" /> -->
<!--        </h:commandLink> -->

Then 不会抛出异常,但仍然被调用。

这是怎么造成的,如何解决?

jsf comments el facelets propertynotfoundexception
3个回答
20
投票

仔细查看堆栈跟踪。这是相关部分:

...
org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:189)
com.sun.faces.facelets.el.ELText$ELTextVariable.toString(ELText.java:217)
com.sun.faces.facelets.el.ELText$ELTextComposite.toString(ELText.java:157)
com.sun.faces.facelets.compiler.CommentInstruction.write(CommentInstruction.java:77)
...

因此它在注释块中评估 EL(可通过

CommentInstruction
识别)。注释块被视为模板文本。默认情况下,Facelets 也会评估模板文本中的 EL
#{}
。就像您在编写
<p>#{screenShotBean.takeScreenshot}</p>
时没有任何 JSF 标签一样。

您有多种选择:

  1. 完全删除评论块。

  2. 通过在注释中添加

    \
    前缀来转义 EL 表达式,如

    所示
     \#{screenShotBean.takeScreenshot}
    

    这样他们就不会被评价。

  3. 将整个注释块包裹在

    <ui:remove>
    中,这样它就不会出现在组件树中(也不会出现在生成的 HTML 输出中)。

  4. 通过将以下上下文参数添加到 web.xml 来禁用 Facelets 对

    all
    注释的解析:

     <context-param>
         <param-name>jakarta.faces.FACELETS_SKIP_COMMENTS</param-name>
         <param-value>true</param-value>
     </context-param>
    

    请注意,通过这种方式生成的 HTML 输出中不会出现任何评论。


2
投票

除了 BalusC 已经提供的 选项,您还可以将属性

rendered="false"
添加到您的
commandLink

如果您希望能够快速切换多个组件,您可能需要考虑在 bean 中创建调试属性或使用项目阶段:

rendered="#{facesContext.application.projectStage == 'Development'}"

1
投票

您还可以使用上下文参数来跳过 web.xml 中的注释。

这是参数:

javax.faces.FACELETS_SKIP_COMMENTS 
© www.soinside.com 2019 - 2024. All rights reserved.