Выяснить, почему вызыватели JSF вызываются, когда я не ожидаю, что их вызовут - PullRequest
1 голос
/ 16 августа 2011

Я работаю с jsf 2, и у меня такое поведение, которое мне трудно объяснить или понять.

У меня есть несколько независимых h:form s.

, один из которых выглядит следующим образом:

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

Мой вопрос / проблема заключается в том, что всякий раз, когда я нажимаю вышеупомянутую кнопку,Я вижу, как вызываются другие, не связанные друг с другом методы получения членов бина (которые являются частью других форм).(Через ведение журнала)

Ни в одном из методов получения нет бизнес-логики, но я хотел бы понять причину этого.Благодаря печати stacktrace я убедился, что именно 1015 * действительно зовет их.

Как бы вы посоветовали мне следовать за JSF, чтобы понять, почему их вызывают?В чем может быть причина?

Спасибо!Бен.

ОБНОВЛЕНИЕ

Вот трассировка стека, напечатанная одним из работающих геттеров, которые не должны.Как уже говорилось в комментариях, будет очень сложно включить в этот вопрос все связанные с этим детали, поэтому я бы предпочел получить помощь с инструментами, чтобы найти ответ сам.

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, обновлю, как только у меня будет.

ОБНОВЛЕНИЕ 3

Кажется, проблема возникает с<ui:repeat> значение атрибута.Это код SSCCE, который иллюстрирует проблему:

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

Код компонента:

@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");
}

При нажатии кнопки это выводится в журнал:

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

Почему запускается список?Разве это не избыточно?

1 Ответ

1 голос
/ 16 августа 2011

Я не использую MyFaces, поэтому я не буду вдаваться в его специфику. Но для чего стоит, на Мохарре геттер также называется <ui:repeat>. Тем не менее, стек иммо более ясен в отношении того, что происходит. Вот 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 - это список, для которого вы видите, как вызывается геттер. Если что-то хорошо, этот метод получения должен быть вызван только один раз во время фазы просмотра восстановления. Однако, если он был вызван, например, также на этапе визуализации ответа, вы можете беспокоиться об этом, потому что это было бы совершенно ненужным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...