弄清楚为什么在我不希望调用它们时调用JSF getter [英] Figuring out why JSF getters are called when I don't expect them to be called

查看:98
本文介绍了弄清楚为什么在我不希望调用它们时调用JSF getter的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 jsf 2 ,我得到了一些我很难解释或理解的行为。

I'm working with jsf 2 and I'm getting some behaviour which I find hard to explain or understand.

我有几个独立的 h:表格 s。

其中一个看起来像这样:

one of which looks like this:

<h:form>
    <h:commandButton value="#{text.General_Wipe_Now}" action="#{bean.doThate}" >
        <f:ajax execute="@form" render="@form" />
    </h:commandButton>
    <h:selectBooleanCheckbox value="#{bean.ignoreErrors}">Ignore Errors</h:selectBooleanCheckbox>
</h:form>

我的问题是,无论何时按下前面提到的按钮,我都会看到其他无关的bean成员被调用的getter(是其他形式的一部分)。 (通过记录)

My question/issue is that whenever I press the aformentioned button, I see other, unrelated, bean member getters (that are parts of other forms) being called. (Through logging)

任何getter都没有业务逻辑,但我 喜欢理解这个原因。
通过打印 stacktrace 我确保 JSF 确实是调用它们的那个。

There is no business logic in any of the getters but I would like to understand the reason for this. Through printing stacktrace I made sure that JSF is indeed the one calling them.

您如何建议我按照 JSF 来了解他们被调用的原因?
可能是什么原因?

How would you suggest I follow JSF to understand why they are being called? What could be the reason?

谢谢!
Ben。

Thanks! Ben.

UPDATE

这是打印的堆栈跟踪由一个正在运行但不应该运行的吸气剂。
正如评论中所讨论的那样,在这个问题中包含所有相关的细节是非常复杂的,所以我宁愿得到帮助我自己找到答案的工具。

Here is the stacktrace as printed by one of the getters that are running and are not supposed to . As discussed in the comments, it will be extremely complex to include in this question all of the details that are related so I would rather get help with the tools to find the answer myself.

java.lang.Exception
    at com.aCompanyName.applicationName.beans.aBean.getSomethingFromBean(CurrentDevice.java:382)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at javax.el.BeanELResolver.getValue(BeanELResolver.java:302)
    at javax.el.CompositeELResolver.getValue(CompositeELResolver.java:175)
    at org.apache.myfaces.el.unified.resolver.FacesCompositeELResolver.getValue(FacesCompositeELResolver.java:142)
    at com.sun.el.parser.AstValue.getValue(AstValue.java:116)
    at com.sun.el.parser.AstValue.getValue(AstValue.java:163)
    at com.sun.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:219)
    at org.apache.myfaces.view.facelets.el.TagValueExpression.getValue(TagValueExpression.java:85)
    at org.apache.myfaces.view.facelets.component.UIRepeat.getValue(UIRepeat.java:248)
    at org.apache.myfaces.view.facelets.component.UIRepeat.getDataModel(UIRepeat.java:211)
    at org.apache.myfaces.view.facelets.component.UIRepeat._validateAttributes(UIRepeat.java:530)
    at org.apache.myfaces.view.facelets.component.UIRepeat.visitTree(UIRepeat.java:763)
    at javax.faces.component.UIComponent.visitTree(UIComponent.java:797)
    at javax.faces.component.UIComponentBase.visitTree(UIComponentBase.java:992)
    at javax.faces.component.UIComponent.visitTree(UIComponent.java:797)
    at javax.faces.component.UIComponentBase.visitTree(UIComponentBase.java:992)
    at javax.faces.component.UIComponent.visitTree(UIComponent.java:797)
    at javax.faces.component.UIComponentBase.visitTree(UIComponentBase.java:992)
    at javax.faces.component.UIComponent.visitTree(UIComponent.java:797)
    at javax.faces.component.UIComponentBase.visitTree(UIComponentBase.java:992)
    at javax.faces.component.UIComponent.visitTree(UIComponent.java:797)
    at javax.faces.component.UIComponentBase.visitTree(UIComponentBase.java:992)
    at javax.faces.component.UIComponent.visitTree(UIComponent.java:797)
    at javax.faces.component.UIComponentBase.visitTree(UIComponentBase.java:992)
    at javax.faces.component.UIComponent.visitTree(UIComponent.java:797)
    at javax.faces.component.UIComponentBase.visitTree(UIComponentBase.java:992)
    at javax.faces.component.UIComponent.visitTree(UIComponent.java:797)
    at javax.faces.component.UIComponentBase.visitTree(UIComponentBase.java:992)
    at javax.faces.component.UIComponent.visitTree(UIComponent.java:797)
    at javax.faces.component.UIComponentBase.visitTree(UIComponentBase.java:992)
    at javax.faces.component.UIComponent.visitTree(UIComponent.java:797)
    at javax.faces.component.UIComponentBase.visitTree(UIComponentBase.java:992)
    at javax.faces.component.UIComponent.visitTree(UIComponent.java:797)
    at javax.faces.component.UIComponentBase.visitTree(UIComponentBase.java:992)
    at javax.faces.component.UIComponent.visitTree(UIComponent.java:797)
    at javax.faces.component.UIComponentBase.visitTree(UIComponentBase.java:992)
    at org.apache.myfaces.view.facelets.tag.ui.DebugPhaseListener._doTreeVisit(DebugPhaseListener.java:310)
    at org.apache.myfaces.view.facelets.tag.ui.DebugPhaseListener.afterPhase(DebugPhaseListener.java:286)
    at org.apache.myfaces.lifecycle.PhaseListenerManager.informPhaseListenersAfter(PhaseListenerManager.java:111)
    at org.apache.myfaces.lifecycle.LifecycleImpl.executePhase(LifecycleImpl.java:185)
    at org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:189)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
    at org.apache.openejb.tomcat.catalina.OpenEJBValve.invoke(OpenEJBValve.java:45)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:852)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
    at java.lang.Thread.run(Thread.java:662)

更新2

制作SSCCE时,我会更新一次。

Working on making a SSCCE, will update once I have one.

更新3

< ui:repeat> 值属性似乎出现问题。
这是一个例证问题的SSCCE代码:

The problem seems to occur with <ui:repeat> value attribute. This is a SSCCE code that exemplifies the problem:

<h:body>
    <ui:repeat var="str" value="#{admin.SList}">
        STRING: #{str}
    </ui:repeat>

    <h:form>
        <h:commandButton value="pressie" action="#{admin.doThat}">
            <f:ajax execute="@form"/>
        </h:commandButton>
    </h:form>
</h:body>

Bean代码:

@PostConstruct
public void init()
{
    slist.add("Testing");
    slist.add("This");
    slist.add("Thing");
}

private List<String> slist = new ArrayList<String>();

public List<String> getSList(){
    logger.trace("Getting LIST");
    return slist;
}

public void doThat(){
    logger.trace("DoThat Was Run");
}

按下按钮时,会输出到日志:

When pressing the button, this is output to the log:

2011-08-16 16:55:55,853 TRACE [http-80-2] (AdminBean.java:80) - Getting LIST
2011-08-16 16:55:55,865 TRACE [http-80-2] (AdminBean.java:85) - DoThat Was Run

为什么要运行列表?这不是多余的吗?

Why is getting list run? Is it not redundant?

推荐答案

我不使用MyFaces,所以我不会详细说明。但值得一提的是,在Mojarra上,getter也被称为< ui:repeat> 。但是,对于正在发生的事情,堆栈更加清晰。这是 Thread#dumpStack(),直到 FacesServlet #service()

I don't use MyFaces, so I won't go in its specifics. But for what is worth, on Mojarra the getter is also called for <ui:repeat>. However, the stack is imo more clear as to what is happening. Here's the Thread#dumpStack() until FacesServlet#service():

java.lang.Exception: Stack trace
    at java.lang.Thread.dumpStack(Thread.java:1249)
    at mypackage.Bean.getList(Bean.java:21)
    at sun.reflect.GeneratedMethodAccessor51.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at javax.el.BeanELResolver.getValue(BeanELResolver.java:302)
    at com.sun.faces.el.DemuxCompositeELResolver._getValue(DemuxCompositeELResolver.java:176)
    at com.sun.faces.el.DemuxCompositeELResolver.getValue(DemuxCompositeELResolver.java:203)
    at com.sun.el.parser.AstValue.getValue(AstValue.java:116)
    at com.sun.el.parser.AstValue.getValue(AstValue.java:163)
    at com.sun.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:219)
    at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:109)
    at com.sun.faces.facelets.component.UIRepeat.getValue(UIRepeat.java:272)
    at com.sun.faces.facelets.component.UIRepeat.getDataModel(UIRepeat.java:248)
    at com.sun.faces.facelets.component.UIRepeat.setIndex(UIRepeat.java:442)
    at com.sun.faces.facelets.component.UIRepeat.doVisitChildren(UIRepeat.java:661)
    at com.sun.faces.facelets.component.UIRepeat.visitTree(UIRepeat.java:619)
    at javax.faces.component.UIComponent.visitTree(UIComponent.java:1600)
    at javax.faces.component.UIComponent.visitTree(UIComponent.java:1600)
    at com.sun.faces.application.view.StateManagementStrategyImpl.restoreView(StateManagementStrategyImpl.java:240)
    at com.sun.faces.application.StateManagerImpl.restoreView(StateManagerImpl.java:188)
    at com.sun.faces.application.view.ViewHandlingStrategy.restoreView(ViewHandlingStrategy.java:123)
    at com.sun.faces.application.view.FaceletViewHandlingStrategy.restoreView(FaceletViewHandlingStrategy.java:452)
    at com.sun.faces.application.view.MultiViewHandler.restoreView(MultiViewHandler.java:148)
    at javax.faces.application.ViewHandlerWrapper.restoreView(ViewHandlerWrapper.java:303)
    at com.sun.faces.lifecycle.RestoreViewPhase.execute(RestoreViewPhase.java:189)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    at com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:113)
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:409)
    // Remnant omitted for brevity.

因此,在状态管理需要访问整个组件树的恢复视图阶段,会发生这种情况。 UIRepeat 反过来需要在访问其子项时设置行索引。

It is thus happening during the restore view phase when the state management needs to visit the entire component tree. The UIRepeat in turn needs to set the row index when its children are to be visited.

根据 UIRepeat #doVisitChildren()源行索引设置为 -1 。最终目标是只访问树中的子项,而不是迭代模型值,也不渲染任何东西。它只需要 DataModel ,以便能够设置行索引。 datamodel的值是您正在看到调用getter的列表。如果一切正常,则在恢复视图阶段只应调用此getter一次。但是,如果在例如渲染响应阶段期间调用它,那么您可能会担心这一点,因为它完全没必要。

According to the UIRepeat#doVisitChildren() source the row index is set to -1. The final goal is to just visit its children in the tree, not to iterate over the model value nor to render anything. It just needs the DataModel in order to be able to set the row index. The value of the datamodel is the list for which you're seeing the getter being invoked. If anything is fine, this getter should be invoked only once during restore view phase. However, if it was invoked during for example render response phase as well, then you may be worrying about this because it would have been completely unnecessary.

这篇关于弄清楚为什么在我不希望调用它们时调用JSF getter的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆