问题
Using Payara Server 4.1.2.174 with mojarra 2.2.15.
I have a simple Named Bean with scope 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";
}
}
So I have a simple index.xhtml page with form.
<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>
I can open index.xhtml in two different browser tabs or windows. So, I have the following log:
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}
As we can see there are two different instances of SimpleBean. After that I submit the form of the first tab.
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: {}
If I try to submit form of the second tab the stored earlier instance of SimpleBean (solvo.ee.beans.SimpleBean@49a86248) won't be used, instead the ViewScopeContextManager will create a new instance of SimpleBean class, as we can see in log:
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: {}
I have checked the code of the com.sun.faces.application.view.ViewScopeContextManager.copyViewScopeContextsFromSession method and as I understand this behavior is normal. However If i store request parameters or another important data in my bean I will loose it because the instance will be lost after submitting the first form.
Is there a solution to keep bean associated with the second tab primarily (in my example solvo.ee.beans.SimpleBean@49a86248)?
回答1:
It seems this is a bug with Mojarra and will be fixed in 2.3.10 according to this post: https://github.com/eclipse-ee4j/mojarra/issues/4509#issuecomment-453188481
From the same thread, it looks like Payara have applied the patched without waiting for the 2.3.10 release. Does upgrading to the patched Payara solve the problem for you?
来源:https://stackoverflow.com/questions/47907080/multiple-browser-tabs-or-windows-with-the-same-viewscoped-bean-class