将 Payara Server 4.1.2.174 与 mojarra 2.2.15 结合使用。
我有一个简单的命名 Bean,其范围为 javax.faces.view.ViewScoped。
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: [email protected]()
Finest: Handling PostConstructViewMapEvent
Finest: Handling PreDestroyViewMapEvent
Finest: Destroying @viewscoped beans from view map: {simpleBean=solvo.ee.beans.SimpleBean@2adafd68}
Severe: [email protected]()
Finest: Handling PostConstructViewMapEvent
Finest: Handling PreDestroyViewMapEvent
Finest: Destroying @viewscoped beans from view map: {simpleBean=solvo.ee.beans.SimpleBean@49a86248}
正如我们所看到的,SimpleBean 有两个不同的实例。之后我提交第一个选项卡的表单。
Severe: [email protected]()
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: [email protected]()
Severe: [email protected]()
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 中)?