【问题标题】:Multiple browser tabs or windows with the same ViewScoped bean class具有相同 ViewScoped bean 类的多个浏览器选项卡或窗口
【发布时间】:2018-06-03 01:48:36
【问题描述】:

将 Payara Server 4.1.2.174 与 mojarra 2.2.15 结合使用。

我有一个范围为 javax.faces.view.ViewScoped 的简单命名 Bean。

import java.io.Serializable;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.PostConstruct;
import javax.faces.view.ViewScoped;
import javax.inject.Named;


@Named
@ViewScoped
public class SimpleBean implements Serializable
{
    private final Logger logger = Logger.getLogger(SimpleBean.class.getName());

    @PostConstruct
    private void init()
    {
        logger.log(Level.SEVERE, "{0}.init()", this);
    }

    private String name;

    public String getName()
    {
        return name;
    }

    public void setName(String name)
    {
        this.name = name;
    }

    public String action()
    {
        logger.log(Level.SEVERE, "{0}.action()", this);
        logger.log(Level.SEVERE,"====================");
        logger.log(Level.SEVERE, "name: {0}", getName());
        logger.log(Level.SEVERE,"====================");
        return "submit";
    }
}

所以我有一个带有表单的简单 index.xhtml 页面。

<h:form>
  <h:inputText value="#{simpleBean.name}"></h:inputText>
  <h:link value="To submit" outcome="submit"/>
  <h:commandButton value="Welcome Me" action="#{simpleBean.action()}"/>
</h:form>

我可以在两个不同的浏览器选项卡或窗口中打开 index.xhtml。所以,我有以下日志:

Severe: solvo.ee.beans.SimpleBean@2adafd68.init()
Finest: Handling PostConstructViewMapEvent
Finest: Handling PreDestroyViewMapEvent
Finest: Destroying @viewscoped beans from view map: {simpleBean=solvo.ee.beans.SimpleBean@2adafd68}
Severe: solvo.ee.beans.SimpleBean@49a86248.init()
Finest: Handling PostConstructViewMapEvent
Finest: Handling PreDestroyViewMapEvent
Finest: Destroying @viewscoped beans from view map: {simpleBean=solvo.ee.beans.SimpleBean@49a86248}

我们可以看到 SimpleBean 有两个不同的实例。之后我提交第一个选项卡的表单。

Severe: solvo.ee.beans.SimpleBean@2adafd68.action()
Severe: ====================
Severe: name: First tab
Severe: ====================
Finest: Handling PreDestroyViewMapEvent
Finest: Destroying @viewscoped beans from view map: {simpleBean=solvo.ee.beans.SimpleBean@2adafd68}
Finest: Handling PreDestroyViewMapEvent
Finest: Destroying @viewscoped beans from view map: {}

如果我尝试提交第二个选项卡的表单,则不会使用之前存储的 SimpleBean 实例 (solvo.ee.beans.SimpleBean@49a86248),而是 ViewScopeContextManager 将创建一个 SimpleBean 类的新实例,因为我们可以在日志中看到:

Severe: solvo.ee.beans.SimpleBean@4797f115.init()
Severe: solvo.ee.beans.SimpleBean@4797f115.action()
Severe: ====================
Severe: name: Second tab
Severe: ====================
Finest: Handling PreDestroyViewMapEvent
Finest: Destroying @viewscoped beans from view map: {simpleBean=solvo.ee.beans.SimpleBean@4797f115}
Finest: Handling PreDestroyViewMapEvent
Finest: Destroying @viewscoped beans from view map: {}

我检查了 com.sun.faces.application.view.ViewScopeContextManager.copyViewScopeContextsFromSession 方法的代码,据我了解,这种行为是正常的。 但是,如果我将请求参数或其他重要数据存储在我的 bean 中,我会丢失它,因为在提交第一个表单后实例将丢失。

是否有一种解决方案可以使 bean 主要与第二个选项卡相关联(在我的示例中为 solvo.ee.beans.SimpleBean@49a86248)?

【问题讨论】:

标签: jsf glassfish jsf-2.2 mojarra view-scope


【解决方案1】:

这似乎是 Mojarra 的一个错误,根据这篇文章将在 2.3.10 中修复:https://github.com/eclipse-ee4j/mojarra/issues/4509#issuecomment-453188481

从同一个线程来看,Payara 似乎已经应用了补丁,而无需等待 2.3.10 版本。升级到修补过的 Payara 是否可以解决您的问题?

【讨论】:

    猜你喜欢
    • 2019-07-10
    • 2012-03-14
    • 1970-01-01
    • 2013-12-20
    • 1970-01-01
    • 1970-01-01
    • 2020-06-01
    • 2018-12-12
    • 1970-01-01
    相关资源
    最近更新 更多