无法从 Servlet 过滤器中的 FacesContext 检索 Session

Posted

技术标签:

【中文标题】无法从 Servlet 过滤器中的 FacesContext 检索 Session【英文标题】:Failed to retrieve Session from FacesContext inside a Servlet Filter 【发布时间】:2012-06-16 08:45:43 【问题描述】:

验证我的用户后,我想在会话中添加对当前登录用户的引用。

这是我在setCurrentUser 方法中的做法:

FacesContext facesContext = FacesContext.getCurrentInstance();
HttpSession session = (HttpSession) facesContext.getExternalContext().getSession(true);
session.setAttribute("CURRENT_USER", currentUser);

很遗憾,session 引用始终为空!

或者,我尝试使用 sessionMap

FacesContext facesContext = FacesContext.getCurrentInstance();
Map<String, Object> sessionMap = facesContext.getExternalContext().getSessionMap();
sessionMap.put("CURRENT_USER", currentUser);

由于这个异常,它惨遭失败:

java.lang.UnsupportedOperationException
    at java.util.AbstractMap.put(AbstractMap.java:186)
    (...)

我做错了什么?

我的控制器的完整代码

UserController.java

public class UserController implements Filter 
    private FilterConfig fc;
    private static final String CURRENT_USER = "CURRENT_USER";

    public void init(FilterConfig filterConfig) throws ServletException 
        fc = filterConfig;
        log(">> Filter initialized");
    

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException 
        // Authenticate user
        // ...

        // Save refernce in Session
        setCurrentUser(currentUser);

        //(...)
    

    public static void setCurrentUser(User u) 
        FacesContext facesContext = FacesContext.getCurrentInstance();
        HttpSession session = (HttpSession) facesContext.getExternalContext().getSession(true);
        session.setAttribute(CURRENT_USER, u);// session is always NULL
    

    public static User getCurrentUser() 
        FacesContext facesContext = FacesContext.getCurrentInstance();
        HttpSession session = (HttpSession) facesContext.getExternalContext().getSession(true);       
        return (User)session.getAttribute(CURRENT_USER);
    

    //...   

JSF 2.0JBoss 5.1.0.GA

【问题讨论】:

【参考方案1】:

FacesContextFilter 中不可用,因为FilterFacesServlet 之前调用

您应该改为从 request 参数获取会话。

HttpSession session = ((HttpServletRequest) request).getSession();
session.setAttribute("user", currentUser);
// ...

一旦您在 JSF 上下文中(例如,在 JSF 托管 bean 或 JSF 视图中),那么 getSessionMap() 将可以在相同的属性名称上使用它

User user = (User) externalContext.getSessionMap().get("user");

或者直接通过 EL 中的#user

@ManagedProperty("#user")
private User user;

【讨论】:

【参考方案2】:

这是我所做的:

public class SesionUtil implements Serializable 

    private static final long serialVersionUID = 1L;

    public void setSesionUsuario(String key, Object value) 
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(key, value);
    

    public String getSesionUsuario(String key) 
        return FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get(key).toString();
    

然后,为了初始化会话,我简单地执行了:

@Inject // Inject dependency
private SesionUtil sessionUtil;

...

sessionUtil.setSesionUsuario("nombreUsuario",nombre);

【讨论】:

以上是关于无法从 Servlet 过滤器中的 FacesContext 检索 Session的主要内容,如果未能解决你的问题,请参考以下文章

javaWeb自己定义可排序过滤器注解,解决Servlet3.0下@WebFilter注解无法排序问题

如何从 servlet 中访问相应 servlet 过滤器中的变量集?

从过滤器访问 servlet 注释

从 Web 应用程序中的 servlet 过滤器重定向到上一页

在 servlet 过滤器中向请求添加 HTTP 标头

Servlet和JSP中的过滤器都是Java类