尝试从会话范围的Bean尝试获取.getSessionMap()时,抛出IllegalStateException [英] IllegalStateException when trying to .getSessionMap() from a Session Scoped Bean

查看:138
本文介绍了尝试从会话范围的Bean尝试获取.getSessionMap()时,抛出IllegalStateException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是Java和JSF的新手.我需要有关IllegalStateException的帮助.这是场景:

I'm new to Java and JSF. I need help with an IllegalStateException. Here's the scenario:

在我当前的项目中,我在应用程序菜单中使用了这个Session Scoped bean:

In my current project i have this Session Scoped bean for the application menu:

public final class MenuBean implements Serializable{  
    private MenuModel model;
    private FacesContext context = FacesContext.getCurrentInstance();

    public MenuModel getModel() {
        return model;
    }

    public MenuBean() {
        updateMenu();
    }

    public void updateMenu(){
        Map session = (Map<String,Object>) context.getExternalContext().getSessionMap();
        EUser user = (EUser) session.get(UserBean.USER_SESSION_KEY);

        ...
    }

    private MethodExpression createMethodExpression(String action) {  
        ...  
    }
}

根据我的逻辑,我需要更新菜单,所以我要这样做:

At some point of my logic, i need to update the menu, so i do this:

ExternalContext extContext = context.getExternalContext();
Map sMap = (Map<String,Object>) extContext.getSessionMap();

MenuBean menu = (MenuBean) sMap.get("menuBean");
menu.updateMenu();

bean构造良好,但是当我尝试如上所述手动更新它时,我在更新方法updateMenu()

The bean constructs fine, but when i try to manually update it as shown above, i get and IllegalStateException on the 1st line of the update method updateMenu()

我不明白这是怎么回事,因为我可以在第一次构建菜单时通过相同的调用获得会话映射.

I don't understand what's wrong, since I can get the session map with that same call whe the menu is build in the first time.

此外,使用NetBeans调试器,我可以看到MenuBean实例已正确恢复.

Also, using the NetBeans debugger, i can see that the instance of MenuBean is correctly recovered.

你们能帮我吗?

推荐答案

FacesContext存储在HTTP请求线程中.您绝对不应该将其声明为实例的实例变量并将其分配给其寿命比HTTP请求更长的实例变量(最好也不要仅在基于请求的情况下才这样做-这是错误的设计). HTTP请求完成后,FacesContext实例将被释放并无效.在任何后续的HTTP请求中,该实例不再有效.有一种非法状态的手段.这就解释了您所看到的IllegalStateException.

The FacesContext is stored in the HTTP request thread. You should absolutely not declare and assign it as an instance variable of an instance which lives longer than the HTTP request (and preferably also just not when it's already request based -it's bad design). The FacesContext instance is released and invalidated when the HTTP request finishes. In any subsequent HTTP request the instance is not valid anymore. There's means of an illegal state. That explains the IllegalStateException you're seeing.

您需要删除以下行:

private FacesContext context = FacesContext.getCurrentInstance();

并修复您的代码,使其仅在方法块中变为threadlocal:

And fix your code to get it only threadlocal in the method block:

Map<String, Object> sessionMap = FacesContext.getCurrentInstance().getExternalContext().getSessionMap();
// ...

您始终可以将其分配为变量,但是应仅将其保留为线程局部变量:

You can always assign it as a variable, but that should only be kept threadlocal:

FacesContext context = FacesContext.getCurrentInstance();
Map<String, Object> sessionMap = context.getExternalContext().getSessionMap();
// ...


无关与具体问题无关,在这种特殊情况下使用@ManagedProperty更为容易.


Unrelated to the concrete problem, using @ManagedProperty has been easier in this particular case.

public final class MenuBean implements Serializable {  

    @ManagedProperty("#{user}")
    private EUser user;

    // ...
}

然后,JSF将为您注入.

JSF will then inject it for you.

这篇关于尝试从会话范围的Bean尝试获取.getSessionMap()时,抛出IllegalStateException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆