问题
I'm using spring-session and I really like it. However I think I'm missing something. In my application the flow goes like this:
1) User requests HomepageController
and that controller tries to put an attribute in the request:
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
final String sessionIds = sessionStrategy.getRequestedSessionId(request);
if (sessionIds != null) {
final ExpiringSession session = sessionRepository.getSession(sessionIds);
if (session != null) {
session.setAttribute("attr", "value");
sessionRepository.save(session);
model.addAttribute("session", session);
}
}
As you can see it will try to get the sessionID from the request-cookie, and if there's a session with that ID in the repository than use it (add attribute). This is perfect, but only after the second request. Why? Because if I restart the server than the cookie is left with the old value, and then the first request will not find the session in the repository. After the response is committed though the cookie will be updated, so the second request will be correct. And here's the question: what is wrong with my logic and how should one develop the application in order to support the first request too?
BTW, here's a sample application that demonstrates the problem:
https://github.com/paranoiabla/spring-session-issue
回答1:
If you are wanting to obtain the session, you should not use requested session id. The requested session id is just that...what the browser requests. Some problems with using requested session (some of which you already outlined):
- If you clear all your cookies and make a request, then no session is requested by the browser.
- As you pointed out if the data store is restarted and is not persistent, then the requested session id is invalid
- If the session expires, then the requested session will be invalid
Instead, you should use the session id:
final String sessionIds = request.getSession().getId();
This will use the requested session id if it is valid, otherwise it will create a new session and ensure the session is written to the response (i.e. included in the response as a cookie).
回答2:
I would say your approach is wrong, your controller does to much and you should be just using the HttpSession
for which Spring Session provides support. You shouldn't also be putting the session in the model
imho as you should be just accessing the HttpSession
. Your application shouldn't know about Spring Session.
Your controller should look like this
@Controller
public class HomepageController {
@RequestMapping(value = "/", method = RequestMethod.GET)
public String home(HttpSession session) {
session.setAttribute("attr", "value");
return "homepage";
}
}
if you don't want to force session creation inject the HttpServletRequest
and do getSession(false)
instead of injecting the HttpSession
.
Everything else (storing the session after request handling etc.) will be handled transparently by Spring Session.
来源:https://stackoverflow.com/questions/29539781/session-is-null-on-first-request