从Servlet过滤器访问时,会话属性映射中的object为null [英] object is null in the session attribute map when accessed from servlet filter

查看:94
本文介绍了从Servlet过滤器访问时,会话属性映射中的object为null的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a servlet filter to force user authentication. It checks for the existence of a non-null object in the HttpSession. For some reason that I cannot figure out, the session contains an object with the correct name, but HttpSession.getAttribute is returning as null. Here is the process that it goes through.

在登录页面上,它调用一个包含以下用户验证代码的操作.在这一点上,我100%确保对象"login"不为空.

from the login page, it calls an action which contains the following user validation code. At this point I am 100 percent sure the object "login" is not null.

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

结果欢迎"将转到包含以下代码的facelet页面:

The outcome 'Welcome' goes to a facelet page with the following code in it:

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

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

This code does successfully show the email address, thus confirming that there is a loginBean object in session scope, and its not null. A command link on that welcome page submits a request to a different view. When the servlet filter intercepts the request, it does the following:

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.我似乎无法解决这一个谜.有什么建议?

Its ALWAYS sending the user back to the login page, because the beanObj is always coming back null. This is a mystery I cannot seem to solve. Any suggestions?

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

EDITED For further debugging I added logging code into the servlet filter to dump the attributes in the session:

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

输出确认会话中有一个名为"loginBean"的属性!这太疯狂了...

The output confirms that there IS an attribute named "loginBean" in the session! This is maddening...

已编辑

如果字符不可见,我将完全重新键入bean的名称,然后进行完整的清除/重新发布以确保获得最新的代码.

In case of invisible characters, I completely retyped the name of the bean, and then did a full clean/republish to make sure I was getting the newest code.

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容器)上.

I registered an HttpSessionAttributeListener. The output confirms that the bean was added into the session. There are no subsequent instances of that bean getting replaced or removed from the session. I'm not sure how to proceed with using a debugger, especially on something as complex as this (an entire web container running in the JVM.)

推荐答案

好,我现在觉得很蠢. servlet过滤器代码中有一个错误.实际上是两个.首先是在一次doFilter(request,response)方法调用之后,我丢失了一个"return"语句.第二个是JSESSIONID被附加到URL上,而我在始终允许登录页面的代码中没有考虑到这一点.好吧,实际上我试图解决这个问题,但是我做错了.我写的好像是JSESSIONID是一个查询参数,就像这样吗?JSESSIONID = blah,实际上它不是查询参数,而是使用分号:; JSESSIONID = blah.

Ok, I feel dumb now. It was a mistake in the servlet filter code; two actually. The first was I was missing a 'return' statement after one of the doFilter(request,response) method calls. The second was that JSESSIONID was getting appended to the URL and I didn't account for this in the code that always permits the login page. Well, actually I tried to account for it but I did it incorrectly. I had written it as if JSESSIONID was a query parameter, like this ?JSESSIONID=blah when in actuality it is not a query parameter, it uses a semicolon like this: ;JSESSIONID=blah.

这些错误的结合使servlet过滤器看起来无法在会话中找到对象;但是实际发生的是该日志消息来自PREVIOUS请求-当bean实际存在时,它从未检查过后续请求的会话.哎呀!对于以后遇到此问题的人,我将告诉您如何解决:我从进行转发或重定向的servlet过滤器中删除了所有代码,并在底部放置了一个doFilter(),然后放入了日志记录语句看到价值.随即可见发生了什么事. HttpSessionAttributeListener也很有帮助.

The combination of these bugs made it look like the servlet filter was not able to locate the object in session; but what was actually happening was that log message was from the PREVIOUS request -- it never got as far as checking the session on subsequent requests when the bean was actually there. Whoops! For those who have this problem in the future, I'll tell you how I figured it out: I removed all code from the servlet filter that did forwarding or redirect and put a single doFilter() at the bottom, and then put logging statements to see the value. It was then immediately apparent what was happening. The HttpSessionAttributeListener was helpful as well.

这篇关于从Servlet过滤器访问时,会话属性映射中的object为null的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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