Weld 1.0.1-Final: bean-объект Conversation Scope остается воссозданным даже после начала разговора? - PullRequest
2 голосов
/ 04 апреля 2011

Я сейчас использую:

  1. Apache tomcat 7
  2. JBoss Weld servlet 1.0.1-Final
  3. empty beans.xml
  4. <listener-class>org.jboss.weld.environment.servlet.Listener</listener-class> в web.xml

В настоящее время я тестирую простой счетчик bean-компонента @ConversationScoped, и после начала области диалога планируется продолжать увеличивать счетчик при каждом нажатии кнопки.

Но похоже, что после отправки бин всегда будет воссоздан, даже после того, как я начну разговор с 1-го места.

Вот мой простой боб:

package user.ui;

import java.io.Serializable;

import javax.annotation.PostConstruct;
import javax.enterprise.context.Conversation;
import javax.enterprise.context.ConversationScoped;
import javax.inject.Inject;
import javax.inject.Named;

@Named
@ConversationScoped
public class CounterBean implements Serializable {
    @Inject
    private Conversation conversation;

    @PostConstruct
    public void init() {
        System.out.println("beginning conversation : " + this.conversation);
        this.conversation.begin();
    }

    private int counter;

    public int getCounter() {
        return counter;
    }

    public void setCounter(int counter) {
        this.counter = counter;
    }

    public void increment() {
        this.counter++;
    }
}

Вот мое простое представление jsf:

<ui:composition template="/template/masterlayout.xhtml">
    <ui:define name="windowTitle">Test Conversation Scope</ui:define>
    <ui:define name="heading">Test Conversation Scope</ui:define>
    <ui:define name="content">
        <h:form>
            <p:messages id="messages" globalOnly="true" />
            <p:panel header="Test Conversation Scope">
                <h:outputText value="counter : " /> #{counterBean.counter}
            </p:panel>

            <h:commandButton value="Submit Data to Server" action="#{counterBean.increment}" />
        </h:form>
    </ui:define>
</ui:composition>

Вот файл журнала для первого доступа:

INFO: Server startup in 12055 ms
beginning conversation : ID: 1, transient: true, timeout: 600000ms

И после того, как представление отобразилось, я нажал на кнопку, и в этом журнале catalina.out возникает исключение:

beginning conversation : ID: 2, transient: true, timeout: 600000ms
unhandled exception : org.jboss.weld.context.ContextNotActiveException: WELD-001303 No active contexts for scope type @ConversationScoped
cause exception : org.jboss.weld.context.ContextNotActiveException: WELD-001303 No active contexts for scope type @ConversationScoped, cause exception is BE : false

Вот трассировка исключения из журнала tomcat:

Apr 4, 2011 3:56:27 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [Faces Servlet] in context with path [/primebert] threw exception [WELD-001303 No active contexts for scope type @ConversationScoped] with root cause
org.jboss.weld.context.ContextNotActiveException: WELD-001303 No active contexts for scope type @ConversationScoped
    at org.jboss.weld.conversation.ConversationImpl.checkConversationActive(ConversationImpl.java:79)
    at org.jboss.weld.conversation.ConversationImpl.isTransient(ConversationImpl.java:234)
    at org.jboss.weld.conversation.ConversationImpl.toString(ConversationImpl.java:199)
    at java.text.MessageFormat.subformat(MessageFormat.java:1246)
    at java.text.MessageFormat.format(MessageFormat.java:836)
    at java.text.Format.format(Format.java:140)
    at java.text.MessageFormat.format(MessageFormat.java:812)
    at ch.qos.cal10n.MessageConveyor.getMessage(MessageConveyor.java:89)
    at org.jboss.weld.logging.WeldMessageConveyor.getMessage(WeldMessageConveyor.java:78)
    at org.slf4j.cal10n.LocLogger.debug(LocLogger.java:95)
    at org.jboss.weld.conversation.ConversationImpl.switchTo(ConversationImpl.java:190)
    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 org.jboss.weld.util.reflection.SecureReflections$13.work(SecureReflections.java:304)
    at org.jboss.weld.util.reflection.SecureReflectionAccess.run(SecureReflectionAccess.java:54)
    at org.jboss.weld.util.reflection.SecureReflectionAccess.runAsInvocation(SecureReflectionAccess.java:163)
    at org.jboss.weld.util.reflection.SecureReflections.invoke(SecureReflections.java:298)
    at org.jboss.weld.bean.proxy.ClientProxyMethodHandler.invoke(ClientProxyMethodHandler.java:113)
    at org.jboss.weld.util.CleanableMethodHandler.invoke(CleanableMethodHandler.java:43)
    at org.jboss.weld.conversation.ConversationImpl_$$_javassist_2.switchTo(ConversationImpl_$$_javassist_2.java)
    at org.jboss.weld.conversation.AbstractConversationManager.beginOrRestoreConversation(AbstractConversationManager.java:137)
    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 org.jboss.weld.util.reflection.SecureReflections$13.work(SecureReflections.java:304)
    at org.jboss.weld.util.reflection.SecureReflectionAccess.run(SecureReflectionAccess.java:54)
    at org.jboss.weld.util.reflection.SecureReflectionAccess.runAsInvocation(SecureReflectionAccess.java:163)
    at org.jboss.weld.util.reflection.SecureReflections.invoke(SecureReflections.java:298)
    at org.jboss.weld.bean.proxy.ClientProxyMethodHandler.invoke(ClientProxyMethodHandler.java:113)
    at org.jboss.weld.util.CleanableMethodHandler.invoke(CleanableMethodHandler.java:43)
    at org.jboss.weld.conversation.ServletConversationManager_$$_javassist_0.beginOrRestoreConversation(ServletConversationManager_$$_javassist_0.java)
    at org.jboss.weld.jsf.WeldPhaseListener.initiateSessionAndConversation(WeldPhaseListener.java:171)
    at org.jboss.weld.jsf.WeldPhaseListener.beforeRestoreView(WeldPhaseListener.java:118)
    at org.jboss.weld.jsf.WeldPhaseListener.beforePhase(WeldPhaseListener.java:87)
    at com.sun.faces.lifecycle.Phase.handleBeforePhase(Phase.java:228)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:99)
    at com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:111)
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:312)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:306)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:541)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:383)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:243)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:188)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:288)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:662)

Есть идеи, что пошло не так?

Спасибо!

Ответы [ 3 ]

2 голосов
/ 10 сентября 2013

Чтобы отслеживать длительный разговор, Weld вставляет параметр cid в метод action формы HTML.

В вашем случае вы начинаете длительный разговор в методе PostConstruct counterBean. Но ссылка на counterBean сначала указывается внутри h:form, поэтому к моменту инициализации counterBean заголовок h:form уже был обработан. Вы должны начать разговор раньше.

Я не уверен, что лучший способ сделать это. Наверное, так:

<f:metadata>
    <f:event type="preRenderView" listener="#{someBean.init}"/>
</f:metadata>

Вы можете начать разговор только по GET-запросу:

public void init() {
    if (!FacesContext.getCurrentInstance().isPostback()) {
        conversation.begin();
    }
}

JSF 2.2 имеет тег <f:viewAction> (аналогичный действиям на странице шва), который можно использовать для достижения той же цели.

В качестве альтернативы вы можете просто поместить это выражение EL над формой:

#{javax.enterprise.context.conversation.begin()}

Но тогда вы должны быть осторожны, чтобы не перерисовать это выражение снова.


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

1 голос
/ 11 ноября 2011

Мы видели то же самое, поэтому обходя его, мы выполняем перенаправление на страницу, как только мы начинаем разговор. Мы знаем, какие части нашего приложения нуждаются в диалогах на основе префикса id формы, поэтому можем сделать это на раннем этапе прослушивания. После Restore View работает хорошо. У меня проблемы с выполнением перенаправлений из представления перед восстановлением, которые были бы более идеальными.

В итоге я использовал HttpServletRequest из FacesContext.getExternalContext (). GetRequest (), который может дать полный URL-адрес для перенаправления. Я разбил его на код и перекомбинировал - структуру нашего кода и многократно используемый класс для содержания понятия формы и параметров. SendRedirect с удаленной обработкой исключений -

ExternalContext external = faces.getExternalContext();
String baseUrl = external.getRequestContextPath() + m_formId;
String target = external.encodeRedirectURL(baseUrl, m_requestParameters);
external.redirect(target);
1 голос
/ 21 апреля 2011

С точки зрения CDI, ваш код должен работать (на самом деле он работает на JBoss AS 6). Кажется, что происходит то, что диалог не распространяется между двумя запросами, но это должно быть неявным при использовании отправки формы JSF. Я предполагаю, что у вас неправильные настройки, а Tomcat настроен неправильно.

В качестве первого шага попробуйте передать идентификатор разговора вручную, как описано здесь .

...