我有一个非常简单的应用程序,在 WebLogic 10.3.2 (11g)、Seam 2.2.0.GA 上只有 2 个页面。我在每个中都有一个命令按钮,它会在发布后重定向到另一个。这很好用,因为我在地址栏中看到了当前页面的 URL。
但是,即使我没有定义长时间运行的对话,在随机点击次数之后,并且 - 我认为 - 在随机秒数之后(~ 10 秒 - 60 秒)我在这篇文章的末尾得到了一个可爱的异常(exception)。
现在,如果我已经了解重定向发生时临时对话的工作原理:
- 当我第一次看到我的应用程序时,url 是 http://localhost:7001/myapp
当我点击 pageA.xhtml 中的按钮时,我最终进入了“pageB.xhtml?cid=26”。这是正常的,因为 Seam 将第一个请求的临时 session 扩展到重定向的 renderResponse 阶段。因此,它使用扩展的临时对话的 cid(对话 ID)来查找任何传播的参数。
当我点击 pageB.xhtml 中的按钮时,我最终进入了 pageA.xhtml?cid=26
相同的 cid 被赋予了新的扩展临时对话。这是正常的,因为对话在之前的重定向后发布结束时结束,而不是数字 26 可以免费用作 cid。
这一切都正确吗?如果是,为什么会发生这种情况:如果我重新键入应用程序的主地址(显示 pageA)并重新单击,我最终会进入 pageB.xhtml?cid=29,这与 26 不同。但是 26 已经结束在之前的 RenderResponse 阶段之后,我重新输入了 url。为什么不使用它而不是 29?
所以,作为补充,有 2 个问题:
- 为什么我会得到异常,即使我没有开始任何长时间运行的对话?
- cid 到底发生了什么?它在什么基础上发生变化?
干杯,
更新:
附加信息:我在页面 A 中使用这样的 h:commandButtons:
<h:commandButton action="showPageB" value="Show page B" />
在B页
<h:commandButton action="showPageA" value="Show page A" />
导航页面A.page.xml:
<page view-id="/pageA.xhtml">
<navigation>
<rule if-outcome="showPageB">
<redirect view-id="/pageB.xhtml" />
</rule>
</navigation>
</page>
和 pageB 非常相似。
至于 session 超时,我设置为1h。请注意,这是无关紧要的,因为正如我所读的here ,它仅用于背景对话。堆栈跟踪如下:
Error 500--Internal Server Error
java.lang.IllegalArgumentException: Stack must not be null
at org.jboss.seam.core.ConversationEntry.(ConversationEntry.java:45)
at org.jboss.seam.core.ConversationEntries.createConversationEntry(ConversationEntries.java:53)
at org.jboss.seam.core.Manager.createConversationEntry(Manager.java:664)
at org.jboss.seam.core.Manager.beforeRedirect(Manager.java:836)
at org.jboss.seam.faces.FacesManager.beforeRedirect(FacesManager.java:66)
at org.jboss.seam.faces.FacesManager.redirect(FacesManager.java:182)
at org.jboss.seam.faces.Navigator.redirect(Navigator.java:55)
at org.jboss.seam.navigation.RedirectNavigationHandler.navigate(RedirectNavigationHandler.java:61)
at org.jboss.seam.navigation.Rule.execute(Rule.java:101)
at org.jboss.seam.navigation.Navigation.navigate(Navigation.java:58)
at org.jboss.seam.navigation.Pages.navigate(Pages.java:203)
at org.jboss.seam.jsf.SeamNavigationHandler.handleNavigation(SeamNavigationHandler.java:42)
at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:130)
at javax.faces.component.UICommand.broadcast(UICommand.java:387)
at org.ajax4jsf.component.AjaxViewRoot.processEvents(AjaxViewRoot.java:324)
at org.ajax4jsf.component.AjaxViewRoot.broadcastEvents(AjaxViewRoot.java:299)
at org.ajax4jsf.component.AjaxViewRoot.processPhase(AjaxViewRoot.java:256)
at org.ajax4jsf.component.AjaxViewRoot.processApplication(AjaxViewRoot.java:469)
at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:82)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:100)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:265)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:227)
at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:125)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:292)
at weblogic.servlet.internal.TailFilter.doFilter(TailFilter.java:26)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)
at org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:530)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)
at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:83)
at org.jboss.seam.web.IdentityFilter.doFilter(IdentityFilter.java:40)
at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
at org.jboss.seam.web.MultipartFilter.doFilter(MultipartFilter.java:90)
at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
at org.jboss.seam.web.ExceptionFilter.doFilter(ExceptionFilter.java:64)
at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
at org.jboss.seam.web.RedirectFilter.doFilter(RedirectFilter.java:45)
at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
at org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:178)
at org.ajax4jsf.webapp.BaseFilter.handleRequest(BaseFilter.java:290)
at org.ajax4jsf.webapp.BaseFilter.processUploadsAndHandleRequest(BaseFilter.java:388)
at org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:515)
at org.jboss.seam.web.Ajax4jsfFilter.doFilter(Ajax4jsfFilter.java:56)
at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
at org.jboss.seam.web.LoggingFilter.doFilter(LoggingFilter.java:60)
at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
at org.jboss.seam.web.HotDeployFilter.doFilter(HotDeployFilter.java:53)
at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
at org.jboss.seam.servlet.SeamFilter.doFilter(SeamFilter.java:158)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)
at weblogic.servlet.internal.RequestEventsFilter.doFilter(RequestEventsFilter.java:27)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3592)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:121)
at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2202)
at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2108)
at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1432)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:201)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:173)
最佳答案
首先,在尝试调试问题时查看相关代码和堆栈跟踪总是有帮助的。
因此我无法回答您的第一个问题。不过,我将尝试解释对话模型的工作原理。
这是来自 Seam in Action 一书:
@ScopeType.EVENT = 从恢复 View 到呈现响应,但不重定向
@ScopeType.CONVERSATION = 从 Restore VIew 转到 Render Response,然后重定向。如果是长时间运行的对话,那么它会跨越多个 JSF 生命周期。
假设您在 a.xhtml
中,您按下一个按钮,该按钮将获取 ComponentA
并在其中填充一些数据。您要在 b.xhtml
中注入(inject)和使用的组件
即:
Push commandbutton in a.xhtml performing post, put some data in ComponentA
现在您重定向到使用 ComponentA
b.xhtml
)
@Name("componentB")
@Scope(ScopeType.CONVERSATION)
public class ComponentB {
@In(create=true)
ComponentA componentA; //OK
}
因此,如果您现在从 b.xhtml
中按下另一个按钮,希望能够再次注入(inject) ComponentA
,那将会失败。
即:
@Name("componentC")
@Scope(ScopeType.CONVERSATION)
public class ComponentC {
@In(create=true)
ComponentA componentA; //Injection of the component you really want fails (you will get default component)
}
所以现在在后台,seam 已经为您创建了一个新的 cid,结束了之前的 cid,因为对话范围的组件只能接受一个请求。
关于java - 没有长时间运行的对话 - IllegalArgumentException : Stack must not be null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2629759/