views:

221

answers:

3

For each servlet request I get, I pass, perhaps, 10 methods before I am at where I need to check something in the session and I need the HttpSession.

The only way I can get the HttpSession is from the HttpServletRequest, correct?

How do I keep track of the session for each servlet request? Unfortuantly I cannot simple make a singleton (ex, SessionInformation.instance().getAttribute("name")) because that session would then be used over all requests.

Is there a way to store the session globally for each request without having to pass it (or it's information) down all the methods just in case I need it?

Update 1:

Alohci pushed me into the right direction. I need something that can either:

1) Manage to store variables globally only over a Thread. A "Singleton-per-Thread" solution?

2) Or is there a unique id for each thread/request a servlet gets? If so, what?

+2  A: 

How do I keep track of the session for each servlet request?

The server identifies its users by marking them through a cookie that holds a session ID on their browsers. On the server the session is where you place data that you need to keep track of during the client/server interaction (to give state to the application).

session.setAttribute("name", SerializableObject)

Note: Because App Engine stores session data in the datastore and memcache, all values stored in the session must implement the java.io.Serializable interface.

You can then grab the session out of a HttpServletRequest by doing

request.getSession()

see javadoc: here

After you retrieve the session inside your servlet, you use session.getAttribute("name") to retrieve whatever data you were interested in to keep track of the interaction.

Is there a way to store the session globally for each request

Why store it globally when the only thing that has the ID to access the session is the servlet that got a request that came with that session ID. Not everything in your application needs to know about every request.

Here is an example of a request that comes with a session ID cookie:

GET /something.htm HTTP/1.1     
Accept: www/source     
Accept: text/html     
Cookie: sessid=123456789

You can't store this information globally, it is unique to each request.

Without having to pass it

When doing useful things with the data, don't pass the session to your methods, pass the useful information, like user name, shopping cart content etc.

HttpSession session = request.getSession() //inside a servlet
String userName = session.getAttribute("name");
List<ShoppingItems> items= session.getAttribute("cart");

MakeTheUserPay(userName, items) //no session passing here

Your business logic methods shouldn't even know what a session is. It's more like an artefact.

Bakkal
You wrote "Not everything in your application needs to know about every request." - Thats exactly what will happen if I start to pass down the data in every method. What I want is to use something like "SessionInformation.instance().getAttribute("name"))" whenever I need to get the name from the session. I do not want to read and send down the name to each "Page" that "might" use it.
corgrath
"Thats exactly what will happen if I start to pass down the data in every method.Thats exactly what will happen if I start to pass down the data in every method." --- You do not pass it where it is not going to be used. "I do not want to read and send down the name to each "Page" that "might" use it." --- You pass the object to the portions of the code that are going to need it.What's the problem in doing this?
Bakkal
For me personally, I try and do things generic all the time. For example, my site has "pages" (a class that implements the interface Page) that does both the logic and the render for each page/request I do. But it's not in all pages I need to have the "user name" that is stored in the session, so why should I always send that when I invoke a page? I much rather do a "String username = SessionInformation.instance().getUserName()" in that specific page than always sending it as a method argument.
corgrath
+2  A: 

I think what you want is a java.lang.ThreadLocal variable.

Alohci
This is more what I want. I need to Google it though to see what it really does :)
corgrath
@corgrath see here: http://stackoverflow.com/questions/321757/threadlocal-variables-in-a-servlet
JoseK
+1  A: 

I think you need to use a Context object to pass the state between your presentation tier, and the business tier (I'm assuming that one exists).

The Context object enables you to encapsulate state and pass it across tiers, without having to worry about how the state itself is maintained. You can refer to the Context Object design pattern, in the Core J2EE Patterns book, if you need to get more information in this area.

Vineet Reynolds