问题
I\'ve the following code snippet in my Facelet:
<h:commandLink id=\"cmdbtn\">
<f:ajax event=\"click\" execute=\"@form\"
listener=\"#{screenShotBean.takeScreenshot}\" />
</h:commandLink>
It works fine, but when I outcomment it like this,
<!-- <h:commandLink id=\"cmdbtn\"> -->
<!-- <f:ajax event=\"click\" execute=\"@form\" -->
<!-- listener=\"#{screenShotBean.takeScreenshot}\" /> -->
<!-- </h:commandLink> -->
then it throws the following exception:
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)
When I change the method expression with parentheses as below,
<!-- <h:commandLink id=\"cmdbtn\"> -->
<!-- <f:ajax event=\"click\" execute=\"@form\" -->
<!-- listener=\"#{screenShotBean.takeScreenshot()}\" /> -->
<!-- </h:commandLink> -->
Then doesn\'t throw the exception, but it\'s still invoked.
How is this caused and how can I solve it?
回答1:
Look closer at the stack trace. Here's the relevant part:
...
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)
...
It's thus evaluating EL in a comment block (recognizable by CommentInstruction
). A comment block is considered as template text. Facelets evaluates by default also EL #{}
in template text. It's like as if you're writing <p>#{screenShotBean.takeScreenshot}</p>
without any JSF tag.
You've several options:
Remove the comment block altogether.
Escape EL expressions in the comment by prefixing it with
\
as in\#{screenShotBean.takeScreenshot}
so that they won't be evaluated.
Wrap the entire comment block in <ui:remove> so that it doesn't appear in the component tree (nor in the generated HTML output).
Disable parsing of all comments by Facelets by adding the following context parameter to
web.xml
:<context-param> <param-name>javax.faces.FACELETS_SKIP_COMMENTS</param-name> <param-value>true</param-value> </context-param>
Note that no one comment will end up in generated HTML output this way.
回答2:
In addition to the options BalusC already provided you could also add the attribute rendered="false"
to your commandLink
.
If you have several components you want to be able to toggle quickly, you might want to consider creating a debug property in a bean or use the project stage:
rendered="#{facesContext.application.projectStage == 'Development'}"
回答3:
You could also use the context parameter that skips comments in your web.xml.
This is the parâmeter:
javax.faces.FACELETS_SKIP_COMMENTS
来源:https://stackoverflow.com/questions/14692560/outcommented-facelets-code-still-invokes-el-expressions-like-bean-action-an