Session in java - Any best practises? - java

I came across a code where the session object is obtained in two different ways (or rather wrote in two different ways).
using HttpServletRequest
someMethod(HttpServletRequest request){
HttpSession session = request.getSession();
//getAttribute from session
}
And using HttpSession
anotherMethod(HttpSession session){
//getAttribute from session
}
I went through this article and a question on SO. But i am still have some doubts.
Can someone help me understand what is the difference between these?
UPDATE
Both of these are methods in a spring controller and these are mapped to different ajax calls. I understand that there is a session associated with every request object but when you pass an HttpSession object where does it find the current session object(load all the attributes) or how is it obtained? When I call the method from javascript, I don't pass anything at all.

someMethod(HttpServletRequest request)
In this you are passing the current request object, from which you can obtain your current session and then you can get attributes from it.. You can get the current session object from your request object by using : -
request.getSession(false)
*NOTE: - We pass false as a parameter to getSession(false) to get any existing session.. If no session exist it will return null..
whereas, request.getSession() will always create a new session, so you won't get any prevoius attribute store in other session..
anotherMethod(HttpSession session)
Here you are passing the session object itself from somewhere.. Might be because, your session object contains many attributes, and you don't want to many parameters in the method..
But you should do all this session related task in your Servlet and pass the attribute to the methods of other class..

There is no huge difference between these two, the second method may be used if called multiple times to eliminate one extra method call request.getSession() by keeping session as somewhat like a local cache (with ignorable performance improvement unless called 100s of times).
eg,.
HttpSession session=request.getSession();
getFirstAttr(session);
getSecondAttr(session);
....
getHundredthAttr(session);
If you use the first method, then all the times that method is called one extra request.getSession() is called.

You don't need to float session objects if you have single attribute. Just simply access it using session object.
HttpSession session = request.getSession(true);
session.getAttribute(name);
Now only sensible case where you can float session objects is you have large number of attributes and you want each method to access its own set of attributes. In any case the method depends on session passed to it so it should not care how it was obtained.

Related

properly use session in spring mvc

I use Spring 4.1.1. And I must make service of user session. What's the best way of storing session related data of a user? I read so many way's , but I don't understand which way is proper?
it's example that I need
#Controller
#SessionAttributes("user")
public class PagesController {
#RequestMapping(value="/sign_in", method = RequestMethod.POST)
public String getSignIn(#RequestParam(value="user")String user ,
#RequestParam(value="pass")String password,
Model model) {
UserDAO dao = new UserDao();
if(dao.isUserValid(user,password) && !model.containsAttribute("user")){
User user = new User();
model.addAttribute("user",user);
return USER_PAGE;
}
return LOGIN_PAGE;
}
}
First of all, Session Attribute is not a good option to store your user object. It is spring who decides when to clear a session attribute data. As per spring documentation, spring removes a session attribute when it understands that a 'conversation' is completed. You only use session attribute when you are in a controller scope and the data is temporarily needed to be stored in the session.
As far as user login object goes, the thing you need to do is to use http sesison. When you login/sign in to your application you actually post the login credential to your controller. Once validated, you put the user object (with your necessary info-as less as possible- in to an object and store in to your session). This object will remain as long as it doesn't expire or you clear it when the user trigger logout.
Moreover if you still want to use SessionAttribute to store your user Object. Then there can be further problem when you deploy your application to a clustered environment. Your session will have to be copied to each instance of your server unless you implement sticky session. Copying httpsession is the simplest of task whereas copying the same instance of a sessionAttribute is not.
#RequestMapping(value = "login.html", method = RequestMethod.POST)
public ModelAndView post(#ModelAttribute("login") LoginEntity login, HttpServletRequest req) {
... process the data ...
if passed put it into session:
HttpSession session = req.getSession(true);
UserObject userObject=new UserObject();
userObject.setName(login.getUserName());
...
session.setAttribute("user",userObject);
It is OK that you put your user object in session, and then use it in your project everywhere. However, if you get a lot of users, that means you have many user object in the memory of your server. The memory might run out.
Another way to do it is to put some user information in cookies with some encryption and validation, but just remember not to put too much info in cookies because cookies will be sent every time a request or a response is made. If there to much information to send, it will slow the response time.
And just a reminder, you should call status.setComplete() to clean the attributes inside a session when they are not needed.
Does SessionStatus object.setComplete() clears all the session attributes or just work for the controller in which it is used?
and if you don't know how to use it, you can see the article below
http://vard-lokkur.blogspot.tw/2011/01/spring-mvc-session-attributes-handling.html

Difference between request.getSession() and request.getSession(true)

I understand the difference between request.getSession(true) and request.getSession(false). But request.getSession() & request.getSession(true) look very similar!
Both "return the current session associated with this request", but differ in:
request.getSession():
"or if the request does not have a session, creates one"
request.getSession(true):
"if there is no current session, returns a new session"
I don't understand the difference between them, is it that (if none exists) they create a new session but the first one doesn't return it but the second one does?
Source: http://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpServletRequest.html
Edit:
Someone tagged/marked my question as duplicate even though it isn't. I will explain why.
I have explicitly asked for the difference between request.getSession() & request.getSession(true) and NOT between request.getSession(true) & request.getSession(false)! I have stated , again explicitly, that I already understand the difference b/w ..(true) & ..(false).
The question linked as a possible duplicated of of asks about the difference b/w ..(true) & ..(false) and not ..(true) & ..()
request.getSession() will return a current session. if current session does not exist, then it will create a new one.
request.getSession(true) will return current session. If current session does not exist, then it will create a new session.
So basically there is not difference between both method.
request.getSession(false) will return current session if current session exists. If not, it will not create a new session.
request.getSession() is just a convenience method. It does exactly the same as request.getSession(true).
Method with boolean argument :
request.getSession(true);
returns new session, if the session is not associated with the request
request.getSession(false);
returns null, if the session is not associated with the request.
Method without boolean argument :
request.getSession();
returns new session, if the session is not associated with the request and returns the existing session, if the session is associated with the request.It won't return null.
They both return the same thing, as noted in the documentation you linked; an
HttpSession object.
You can also look at a concrete implementation (e.g. Tomcat) and see what it's actually doing: Request.java class. In this case, basically they both call:
Session session = doGetSession(true);
A major practical difference is its use:
in security scenario where we always needed a new session, we should use request.getSession(true).
request.getSession(false): will return null if no session found.
request.getSession(true) and request.getSession() both do the same thing, but if we use
request.getSession(false) it will return null if session object not created yet.
request.getSession() or request.getSession(true) both will return a current session only . if current session will not exist then it will create a new session.

How to set request parameter to be avaiable within a session if the session is reset for some other reason

String reqParam=request.getParameter("param");
if(reqParam!=null){
HttpSession session=request.getSession(false);
if(session!=null){
session.setAttribute("reqParamInSession", reqParam);
}
}
I use the code above to set a request parameter value into a session when a doFilter method is called. But when the user navigates to a different experience(assume a user that manages three different branches of a shop will have separate experience for each branch) the session is cleared other than the user profile. I don't manage the module that resets the session when the user experience is changed. But I still need the parameter I set in session even if the user has changed experience.
Is there a way to associate the parameter to every request sent regrdless of the session being changed? Or any other way to handle this?
Dont' use application scope as if the session is closed for any reason the params won't be cleared. Use cookies if you can.

custom dropdown box to submit to session variable

this one has been bugging me for a few days
what i would like to do is on one of my views i would like to get a list of Locations (Entity) and submit the selected location to a session variable so i can show relative data according to the location
i'm unsure how to go about setting this up
any response would be appreciated
Since you tagged this with Spring, you can get direct access to the HttpSession object and just shove the data right in there. Your controller method signature would look something like this in Spring 3.0:
public ModelAndView someMeaningfulName(#ModelAttribute Location location, HttpSession httpSession) {
httpSession.setAttribute("location", location);
// Other method code
}
You you have access to the HttpServletRequest object, you can also gain access to the HttpSession from that object as well (request.getSession()). Just be aware, that the HttpSession object may not be thread safe and that the scope of this object is now tied to the User's session.

Java HttpSession

Is HttpSession in java servlet is created only after
HttpSession s = request.getSession();
?
In my code I didn't write that, but when I use if (request.getSession(false) == null) ..., it doesn't work. Why?
A HttpSession is created when calling request.getSession().
But if you access a JSP by default it will automatically create a session.This behaviour can be disabled by using: <%# page session="false">
Are you using JSP?
Read JavaDocs, it says clearly:
This says, request.getSession()
Returns the current session associated with this request, or if the request does not have a session, creates one.
And the other variant request.getSession(isCreate)
Returns the current HttpSession associated with this request or, if there is no current session and create is true, returns a new session.
If create is false and the request has no valid HttpSession, this method returns null.
To make sure the session is properly maintained, you must call this method before the response is committed. If the container is using cookies to maintain session integrity and is asked to create a new session when the response is committed, an IllegalStateException is thrown.
Update
On a bit research, I have found that Session is not created unless request.getSession() is called somewhere. Since, The servlet container uses this interface to create a session between an HTTP client and an HTTP server. There are good chances that your Servlet container creates the Session for you by default.
refer:
Java Doc HttpSession
Discussion on JavaRaunch: is HttpSession created automatically?
But, to be safer side, use request.getSession() to get session, and use request.getSession(false) only when you need to verify if a session has already been created.
In addition to Nishant's answer note that session can be created implicitly by JSP pages unless you configured them not to create a session with <%# page session = "false" %>.
To make it complete:
session is not created, unless you call request.getSession(), in your servlet, use request.getSession(false) to get existing session without creating new session
if you use JSP page, session is automatically created for you - variable session - unless you specify <%# page session="false" %>
even if your session is created automatically, you can use session.isNew() to find out, if it has been newly created
Try to remove session cookies from browser and make another test. If it does not work then some other component is creating a new session before that call.

Categories