Session 如何在servlet过滤器中从JSF会话映射中读取值?

Session 如何在servlet过滤器中从JSF会话映射中读取值?,session,authentication,servlets,jsf-2,servlet-filters,Session,Authentication,Servlets,Jsf 2,Servlet Filters,要使用Java EE webapp进行身份验证,我有一个与LoginBean关联的login.xhtml JSF页面。如果用户提供了有效的登录详细信息,LoginBean会将值保存到会话映射中: FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("session-value", true); 现在,我想在javax.servlet.Filter的LoginFilter实现中读取名为session

要使用Java EE webapp进行身份验证,我有一个与LoginBean关联的login.xhtml JSF页面。如果用户提供了有效的登录详细信息,LoginBean会将值保存到会话映射中:

FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("session-value", true);
现在,我想在javax.servlet.Filter的LoginFilter实现中读取名为session value的值,但每次尝试访问该属性时,控制台都会告诉我该属性为null:

 @Override
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws Exception {
    HttpSession session = ((HttpServletRequest) request).getSession();
    Object attribute = session.getAttribute("session-value");

    if(attribute != null) {
      LOGGER.log(Level.INFO, ":)");
    } else {
      LOGGER.log(Level.INFO, "Attribute is null.");
    }

    chain.doFilter(request, response);
  }

通过调用HttpServletRequest的会话无法访问JSF会话映射吗?

首先,可以在常规筛选器或servlet中访问JSF会话映射。它位于底层会话中,不特定于JSF

处理login.xhtml的FacesServlet(假定您的web.xml faces相关配置正确)是在servlet过滤器之后而不是之前处理的。如果您正在测试该变量,则您看到的消息为空,因为该页面尚未登录用户

如果您希望编写一个强制登录类型筛选器来检查会话中的某些内容,并在项目丢失时重定向到登录页面,那么您希望从筛选器中排除实际登录。规范不支持url映射中的排除,但您可以向筛选器中添加如下代码:

        HttpServletRequest req = ((HttpServletRequest)request);

    if (!req.getRequestURI().contains("login")) {
        //...Process your login code here - force redirect
    } //Otherwise it will allow the next filter or first servlet to process

登录页面处理完毕,下一页被请求操作或强制导航后,过滤器将再次处理并设置您的值。

谢谢您的回答。但是当JSF会话映射将值存储在底层会话中时,如果在登录后第二次点击过滤器,那么我的访问过滤器应该可以从会话中读取这些值?因为当我第二次和第三次点击过滤器时,从会话读取的值也是空的:是的,您将能够在过滤器的所有后续执行中看到“true”值。您发布的代码片段是可靠的,假设它们正在执行。标准做法是在JSF生命周期中将项目存储到会话中,然后在FacesServlet上下文之外的同一会话中检索它们。有很多代码示例与您的非常相似。我只想在存储值的代码周围添加尽可能多的消息。在它执行完您现有的任何其他代码之前,请尝试在同一个LoginBean中检索它。确定。我做到了。首先,执行过滤器,然后在会话中向JSF页面写入一个值,然后在下一次执行过滤器时读取会话值。但是,在过滤器的所有后续执行中,会话似乎都是空的。是我的bean还是我的JSF页面清除了会话?我的JSF页面使用了一个带有命名和RequestScope注释的Bean。听起来您验证了原始问题,发现可以在常规servlet过滤器中读取JSF编写的会话属性。至于为什么过滤器的后续调用不再显示该属性,我只能建议您跟踪所有代码并反复记录该值,直到找到清除该值的位置。另外,如果您正在调用类似于:FacesContext.getCurrentInstance.getExternalContext.invalidateSession;,那么是的,您正在清除会话。