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

Jsf javax.faces.view.ViewScoped bean和多个选项卡问题,jsf,redirect,nullpointerexception,Jsf,Redirect,Nullpointerexception,在JSF应用程序(基于Payara 5.183)中,我使用如下模式在某些操作后重定向用户: @Named @ViewScoped public class ModelViewBean implements Serializable { private Model _model; ... public String delete() { System.out.println(">> Deleting model with ID: " + _mod

在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";
    }
    ...
}
问题:如果有两个或多个页面是用不同的
\u model
对象打开的-操作
delete()
会在第一次执行后导致其他页面上的
\u 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");
    }
    ...
}
我已经录下了

还有示例项目

NPE的原因是什么?在这种情况下,在采取一些行动后,使用导航的最合适方式是什么

谢谢大家!

另外,我已经读过一些主题,但到目前为止还没有找到我的问题的答案

更新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>
NPE:

重现问题的步骤:

  • 打开main.xhtml
  • 同时在两个选项卡(Model1和Model2)中打开两个链接
  • 按Model1第一个选项卡中的“删除”按钮-一切正常
  • 按第二个选项卡中的“删除”按钮,型号2-NPE为
    \u model
    等于
    null
    (我还注意到
    @PostConstruct
    也被触发)
  • 更新2:


    对该专题进行了更新,以反映问题的更根本原因。感谢您提供类似帖子的评论链接。

    我从Wildfly 11->Wildfly 14(Mojarra 2.2.13.SP4->2.3.5.SP2)迁移后也遇到了这个问题

    此演示项目在Wildfly 11上运行,但在Wildfly 14上失败

    看起来ViewMap中的引用已被删除,但实际的ViewScope bean未被销毁


    我希望能够找到这一点。

    JSF2.4并没有作为正式版本存在。将所有JavaEE代码移动到Eclipse是一个奇怪的(Oracle要求的)副作用。示例代码(在Flavor中,应该以内联方式发布。请将stacktrace与NPE一起发布,并明确说明NPE发生在哪一行……而且,您是否确实暗示当bean位于不同的作用域时NPE不会发生?@BalusC谢谢您的问题!根据使用场景-我不能使用任何其他作用域,因为我需要打开t。)两个具有不同模型(实体)的相似页面同时出现。因此,尝试绕过
    @ViewScoped
    bean的使用并没有真正的帮助(即使它可以很好地工作)@Kukeltje感谢您抽出时间查看我的帖子!我已经发布了包含问题根本原因的完整代码。GitHub上的链接提供了完整的项目示例代码。堆栈跟踪非常简单,没有什么特别之处。此外,通过查看我随附的短片,问题本身变得超级自我解释。再次感谢您的时间!另外,这个问题也可以通过JSF 2.3.2在Glassfish 5上重现。尝试其他范围。当然也失败了,您的标题不正确,人们可能会开始尝试解决方案,而不是错误的方向。请再次发布一条类似于
    @org.omnifaces.cdi.ViewScoped
    实现方式的内联线。您也可以尝试一下。当我查看答案中的链接时,这似乎已在WildFly 16中修复。他们将Mojarra 2.3.9的修复后移植到WildFly使用的2.3.5SPx版本。目前,我不相信该问题已在主Mojarra中修复。它已在Payara中修复,然后该修复已用于创建paWildfly 16.0.0.Beta1的非匹配版本。Mojarra的问题仍然存在。
    <?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>
    
    ....
    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;
        }
    }
    
    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)
    ....