javax.faces.view.ViewScoped bean 和多个选项卡问题



在JSF应用程序(基于Payara 5.183(中,我使用如下模式在执行某些操作后重定向用户:

@Named
@ViewScoped
public class ModelViewBean implements Serializable {
private Model _model;
...
public String delete() {
System.out.println(">> Deleting model with ID: " + _model.getId());
_appDaoBean.daoDelete(_model);
return "/main.xhtml?faces-redirect=true";
}
...
}

问题:如果打开了两个或多个页面,其中包含不同的_model对象 - 操作delete()会导致首次执行后在其他页面上_model.getId()NPE。

同时,如下方法工作正常:

@Named
@ViewScoped
public class ModelViewBean implements Serializable {
private Model _model;
...
public void delete() {
System.out.println(">> Deleting model with ID: " + _model.getId());
_appDaoBean.daoDelete(_model);
FacesContext.getCurrentInstance().getExternalContext().redirect("/main.xhtml");
}
...
}

我已经录制了带有该问题的 30 秒视频

此外,示例项目发布在 GitHub 上

NPE 的原因是什么,在这种情况下,在执行某些操作后使用导航的最正确方法是什么?

谢谢!

附言像重定向和导航/前进有什么区别以及何时使用什么这样的主题?我已经阅读了,但到目前为止还没有找到我的问题的答案。

更新 1:

主.xhtml:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:p="http://primefaces.org/ui">
<h:body>
<h:form id="f1">
<h2>Main Page</h2>
<p:link outcome="/model.xhtml" value="Model1">
<f:param name="id" value="1"/>
</p:link>
<br/>
<p:link outcome="/model.xhtml" value="Model2">
<f:param name="id" value="2"/>
</p:link>
</h:form>
</h:body>
</html>

型号.xhtml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:p="http://primefaces.org/ui">
<f:view>
<f:metadata>
<f:viewParam name="id" value="#{modelViewBean.id}" />
<f:viewAction action="#{modelViewBean.initModel}" />
</f:metadata>
<h:body>
<h:form id="f1">
<p:outputLabel value="Model ID: #{modelViewBean.model}" />
<br/>
<p:commandButton value="Delete" action="#{modelViewBean.delete()}" process="@this" update="@form" />
</h:form>
</h:body>
</f:view>
</html>

模型视图豆.java

....
import javax.faces.view.ViewScoped;
....
@Named
@ViewScoped
public class ModelViewBean implements Serializable {
private static final long serialVersionUID = 6400111954793903238L;
private String _id;
private String _model;
private Date _beanCreateTime;

@PostConstruct
private void init() {
System.out.println(">> @PostConstruct -> init()");
_beanCreateTime = new Date();
}

public String initModel() {
System.out.println(">> ViewAction -> initModel()");
if (_id == null || _id.trim().isEmpty()) {
return "/main.xhtml?faces-redirect=true";
}
_model = UUID.randomUUID().toString();
return null;
}

public String delete() {
System.out.println(">> Deleting model with ID: " + _model.toUpperCase());
return "/main.xhtml?faces-redirect=true";
}

public String getId() {
return _id;
}

public void setId(String id) {
this._id = id;
}

public String getModel() {
return _model;
}

public Date getBeanCreateTime() {
return _beanCreateTime;
}
}

NPE:

java.lang.NullPointerException
at local.jsfsample.ModelViewBean.delete(ModelViewBean.java:40)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
....

重现问题的步骤:

  1. 打开主.xhtml
  2. 同时在两个选项卡(模型 1 和模型 2(中打开两个链接
  3. 在使用 Model1 的第一个选项卡中按"删除"按钮 - 一切都很好
  4. 在第二个选项卡中按"删除"按钮,使用 Model2 - NPE,_model等于null(我也注意到@PostConstruct也被触发(

更新 2:

更新了该主题,以反映问题的更根本原因。感谢您在评论中链接到类似帖子。

从野蝇 11 -> 野蝇 14 (Mojarra 2.2.13.SP4 -> 2.3.5.SP2 (移动后我也遇到了这个问题

这个演示项目在 Wildfly 11 上工作,但在 Wildfly 14 上失败。

看起来 ViewMap 中的引用被删除了,但实际的 ViewScoped bean 并没有被销毁。

我已经打开了 https://issues.jboss.org/browse/WFLY-11275,希望能追踪到这一点。

相关内容

  • 没有找到相关文章

最新更新