从servlet过滤器访问时,对象在会话属性映射中为空

时间:2012-03-22 03:19:01

标签: jsf-2 servlet-filters

我有一个servlet过滤器来强制用户身份验证。它检查HttpSession中是否存在非空对象。由于某种原因,我无法弄清楚,会话包含一个具有正确名称的对象,但HttpSession.getAttribute返回为null。这是它经历的过程。

从登录页面调用包含以下用户验证代码的操作。此时,我100%确定对象“login”不为空。

if (passWordIsValid) {
   HttpSession session = getCurrentFacesSession();
   session.setAttribute("loginBean", login);
return "welcome";
} else {
   // error handling here 
}

结果“欢迎”进入小面板页面,其中包含以下代码:

<h:outputText value="Welcome #{sessionScope.loginBean.email}"/>

此代码确实成功显示了电子邮件地址,从而确认会话范围中存在loginBean对象,并且它不为null。该欢迎页面上的命令链接将请求提交给其他视图。当servlet过滤器拦截请求时,它会执行以下操作:

HttpSession session = ((HttpServletRequest) servletRequest).getSession();
Object beanObj = session.getAttribute("loginBean");
if (beanObj!=null) {
   chain.doFilter(servletRequest,servletResponse);
} else {
   // code to send back to login page
}

它总是将用户发送回登录页面,因为beanObj总是返回null。这是一个我似乎无法解决的谜。有什么建议?

EDITED 为了进一步调试,我将日志代码添加到servlet过滤器中以转储会话中的属性:

for (Enumeration<String> e = session.getAttributeNames(); e.hasMoreElements();) {
    log("Found Session attribute="+e.nextElement());
}

输出确认会话中有一个名为“loginBean”的属性!这令人抓狂......

已编辑

如果是不可见的字符,我完全重新输入了bean的名称,然后进行了完整的清理/重新发布以确保我获得了最新的代码。

HttpSession session = ((HttpServletRequest) servletRequest).getSession();
String s = "loginBean";
Object beanObj = session.getAttribute(s);
if (beanObj!=null) {
   chain.doFilter(servletRequest,servletResponse);
} else {
   // code to send back to login page
}

同样的行为......

调试

我注册了一个HttpSessionAttributeListener。输出确认bean已添加到会话中。该bean没有后续实例被替换或从会话中删除。我不确定如何继续使用调试器,尤其是在像这样复杂的事情上(在JVM中运行的整个Web容器。)

1 个答案:

答案 0 :(得分:0)

好的,我现在感到愚蠢。这是servlet过滤器代码中的一个错误;实际上是两个第一个是在一个doFilter(请求,响应)方法调用之后我错过了一个'return'语句。第二个是JSESSIONID被附加到URL,我没有在始终允许登录页面的代码中考虑到这一点。好吧,实际上我试图解释它,但我做错了。我写过它,好像JSESSIONID是一个查询参数,像这样?JSESSIONID = blah,实际上它不是一个查询参数,它使用这样的分号:; JSESSIONID = blah。

这些错误的组合使得看起来servlet过滤器无法在会话中找到对象;但实际发生的事情是日志消息来自PREVIOUS请求 - 当bean实际存在时,它从未在后续请求中检查会话。哎呦!对于那些将来遇到这个问题的人,我会告诉你我是如何理解的:我从servlet过滤器中删除了所有代码,这些代码进行了转发或重定向,并在底部放置了一个doFilter(),然后放入了日志语句看到价值。然后立即明白发生了什么。 HttpSessionAttributeListener也很有用。