JSF 登录过滤器,会话为空

Posted

技术标签:

【中文标题】JSF 登录过滤器,会话为空【英文标题】:JSF login filter, session is null 【发布时间】:2013-02-13 12:56:30 【问题描述】:

我一直在尝试关注this 的回答,但我总是被重定向到我的 login.xhtml(从登录页面登录时除外),因为这...

AppManager am = (AppManager) req.getSession().getAttribute("appManager");

始终为空。 我一直在尝试在登录屏幕上打印出用户信息,无论我如何到达那里,所有字段(用户名、密码、登录...)始终为空,即使我直接从管理页面输入地址(即登录时获得的位置)。 如何保存会话,而不是每次我手动输入地址/离开页面时都被鞭打?

应用管理器:

import java.io.Serializable;
import javax.ejb.EJB;
import javax.enterprise.context.SessionScoped;
import javax.faces.bean.ManagedBean;
import javax.faces.context.FacesContext;
import jobapp.controller.Controller;

@ManagedBean(name="appManager")
@SessionScoped
public class AppManager implements Serializable 
private static final long serialVersionUID = 16247164405L;
    @EJB
    private Controller controller;
    private String username;
    private String password;
    private boolean loggedIn;
    private Exception failure;
    ...
     /**
     * 
     * @param e an exception to handle.
     */
    private void handleException(Exception e) 
        e.printStackTrace(System.err);
        failure = e;
        FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
    

    /**
     * The login method.
     * calls the controllers login method.
     * 
     */ 
    public void login()
        try
            failure = null; 
            loggedIn = controller.login(username, password);

        catch (Exception e)
            handleException(e);
        
    
    /**
     * The logout method.
     * Sets the user's info to null
     * and stops the conversation.
     */
    public void logout()
        username = null;
        password = null;
        loggedIn = false;
        FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
    
...

过滤器:

@WebFilter("/faces/admin.xhtml")
public class LoginFilter implements Filter 
...
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException     
        HttpServletRequest req = (HttpServletRequest) request;
        //TODO fix "am" nullpointer
        AppManager am = (AppManager) req.getSession().getAttribute("appManager");
        if (am != null && am.isLoggedIn()) 
            // User is logged in, so just continue request.
            chain.doFilter(request, response);
         else 
            // User is not logged in, so redirect to login.
            HttpServletResponse res = (HttpServletResponse) response;
            res.sendRedirect(req.getContextPath() + "/faces/login.xhtml");
        
    

【问题讨论】:

为了避免显而易见,@SessionScoped 注释来自javax.faces.bean 包,对吧? " 我总是被重定向到我的 login.xhtml (从登录页面登录时除外)" 这不是重点吗?用户必须登录或AppManager 为空? @BalucC @SessionScoped 来自 javax.enterprise.context.SessionScoped @kolossus 不,这不是重点,如果我登录然后在同一个或另一个窗口中输入管理页面的地址(登录时),我什至会被重定向到登录虽然我没有注销。如果那是重点,我会跳过整个 if else 并且无论如何都直接重定向。 【参考方案1】:

@SessionScoped 来自 javax.enterprise.context.SessionScoped

这个只能与 CDI @Named 结合使用。当您使用 JSF @ManagedBean 时,您应该改用 javax.faces.bean 包中的范围注释。

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;

@ManagedBean
@SessionScoped
public class AppManager implements Serializable 

如果没有有效范围,JSF 托管 bean 的行为类似于 @RequestScoped,这实际上意味着它会在每次请求时一次又一次地构造。

【讨论】:

以上是关于JSF 登录过滤器,会话为空的主要内容,如果未能解决你的问题,请参考以下文章

如何从过滤器中读取 JSF 会话 bean?

在 Web 过滤器中访问会话范围的 JSF 托管 bean

JSF 2.0 每页生成多个请求

JSF过滤器在初始重定向后不重定向[关闭]

为啥自动装配的 bean 为空?

如何在 JSF 中实现登录过滤器?