弄清楚为什么在我不希望调用它们时调用JSF getter
我正在使用jsf 2
,我得到了一些我很难解释或理解的行为。
我有几个独立的h:form
s。
其中一个看起来像这样:
Ignore Errors
我的问题是,无论何时按下前面提到的按钮,我都会看到其他不相关的bean成员getter(也是其他forms的部分)被调用。 (通过记录)
任何getter都没有业务逻辑,但我想了解其原因。 通过打印stacktrace
我确保JSF
确实是调用它们的人。
您如何建议我关注JSF
以了解他们被调用的原因? 可能是什么原因?
谢谢! 本。
UPDATE
这是由一个正在运行且不应该运行的getter打印的堆栈跟踪。 正如评论中所讨论的那样,在这个问题中包含所有相关的细节是非常复杂的,所以我宁愿得到帮助我自己找到答案的工具。
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的工作,一旦有了SSCCE,就会更新。
更新3
使用值属性时似乎会出现此问题。 这是一个SSCCE代码,可以解释这个问题:
STRING: #{str}
Bean代码:
@PostConstruct public void init() { slist.add("Testing"); slist.add("This"); slist.add("Thing"); } private List slist = new ArrayList(); public List getSList(){ logger.trace("Getting LIST"); return slist; } public void doThat(){ logger.trace("DoThat Was Run"); }
按下按钮时,会输出到日志:
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
为什么要运行列表? 这不是多余的吗?
我不使用MyFaces,所以我不会详细说明。 但值得一提的是,在Mojarra上,吸气剂也被称为
。 但是,对于正在发生的事情,堆栈更加清晰。 这是Thread#dumpStack()
直到FacesServlet#service()
Thread#dumpStack()
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
反过来需要在访问其子项时设置行索引。
根据UIRepeat#doVisitChildren()
源,行索引设置为-1
。 最终目标是只访问树中的子项,而不是迭代模型值,也不渲染任何东西。 它只需要DataModel
就可以设置行索引。 datamodel的值是您正在看到调用getter的列表。 如果一切正常,则在恢复视图阶段只应调用此getter一次。 但是,如果在例如渲染响应阶段期间调用它,那么您可能会担心这一点,因为它完全没必要。