在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");
}
...
}
我已经记录了30sec video with the issue
还有示例项目is published on the GitHub
发生NPE的原因是什么?在这种情况下采取某些措施后,使用导航的最正确方法是什么?
谢谢!
P.S。到目前为止,What is the difference between redirect and navigation/forward and when to use what?之类的主题我都已阅读,但尚未找到答案。
更新1:
main.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>
model.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>
ModelViewBean.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)
....
重现问题的步骤:
_model
等于null
(我也注意到@PostConstruct
也被触发了)更新2:
该主题已更新,以反映此问题的更根本原因。感谢您对类似文章的评论链接。
答案 0 :(得分:2)
从Wildfly 11-> Wildfly 14(Mojarra 2.2.13.SP4-> 2.3.5.SP2)迁移后,我也遇到了这个问题
此演示项目可在Wildfly 11上运行,但在Wildfly 14上失败。
似乎已删除了ViewMap中的引用,但并未破坏实际的ViewScoped bean。
我已经打开https://issues.jboss.org/browse/WFLY-11275来希望对此进行跟踪。