问题
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.
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
}
The outcome 'Welcome' goes to a facelet page with the following code in it:
<h:outputText value="Welcome #{sessionScope.loginBean.email}"/>
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
}
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?
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());
}
The output confirms that there IS an attribute named "loginBean" in the session! This is maddening...
EDITED
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
}
Same behavior...
debugging
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.)
回答1:
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.
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.
来源:https://stackoverflow.com/questions/9815964/object-is-null-in-the-session-attribute-map-when-accessed-from-servlet-filter