Saturday, 11 March 2017

J2EE: Why do we need sessions? How they Work?

Webservers follow Request and Response model. As soon as you send a request and as soon as you got response, the webservers will forget who you are. The next time you send a request, they don't recognize you. They also don't remember what you have requested in the past and they don't remember what they've sent you in response.

In Enterprise web applications, you need to keep conversational state with the client across multiple requests. This can be achieved through HttpSession in java.


What are the some other alternatives?

1. Use a stateful session enterprise java bean
2. Use a database

we can keep conversational state using the above options, but you would hit with runtime performance.

What HttpSession can do?

1. It can hold conversational state across multiple requests from the same client.
2. In other words, it persists for an entire session with a specific client.
3. we can use it to store everything we get back from the client in all the requests the client makes during a session.

Actual mechanism behind HttpSession:

1. As soon as the client makes first request, the web container generates a unique session ID and gives it back to the client with the response.
2. The client send back the session ID with each subsequent request.
3. The container sees the session ID, finds the matching session, and associates the session with the request.

How client and container exchange Session ID information?

1. Session ID information can be exchanged between client and sever through cookies.
2. Web container, creates a cookie with session ID and sets in response header and forwards the response to client. The name of the header in the response for cookie is Set-Cookie,

Set-Cookie : JSESSIONID=0AAB6C8DE415
3. The client reads the cookie and finds session ID and in subsequent requests, it adds the session ID to cookie and adds to request header. The name of cookie header in request is Cookie

Cookie: JSESSIONID=0AAB6C8DE415

cookies are nothing but name/value String pairs.

How to tell the container to create a session for you?

By default, the container won't create a session for each new request from different clients. You do have to tell the container that you want to create or use a session. This can be achieved through below code.

HttpSession session = request.getSession();

With the above statement, the container creates a session if there is no session created for the earlier requests from this client, else it finds the matching session using session ID and returns that session.

With the call to getSession(), the container takes care of generating session ID, creating a new Cookie object, stuffing the session ID into the cookie, and setting the cookie as part of the response. And on subsequent requests, the Container gets the session ID from the cookie in the request, matches the session ID with an existing session, and associates that session with the current request.

What if the client doesn't accept cookies?

A client with cookies disabled will ignore "Set-Cookie" response headers. If the client doesn't accept cookies, you won't get an exception.

The solution for above problem is URL rewriting. URL rewriting takes the session ID that's in the cookie and sticks it right onto the end of every URL that comes in to this app.

URL +;jsessionid=1234567

for example, www.speakingcs.com;jessionid=1234567

 when the user clicks on the link, the request goes to the Container with that extra bit on the end, and the container simply strips off the extra part of the request URL and uses it to find the matching session.

URL rewriting works only if you tell the response to encode the URL. 

If the cookies don't work, the container falls back to URL rewriting, but you have to encode all the URLs you send in the response. But if you don't explicitly encode your URLs, and the client won't accept cookies, you don't get to use sessions. If you do encode your URLs, the container will first attempt to use cookies for session management, and fall back to URL rewriting only if the cookie approach fails.

 How to enable cookies and URL rewriting in your application?

Use the below code

public void doGet(HttpServletRequest request, HttpServletResponse)
{
     HttpSession session = request.getSession(); // creates or reuses session and also sets cookies
     // do your logic here
     PrintWriter out = response.getWriter();
     out.println("Click me ");
}

How does the container know that cookies aren't working?

When the container sees a call to getSession(), and the Container didn't get a session ID with the client's request, the Container now knows that it must attempt to start a new session with the client. At this point, the Container doesn't know if cookies will work, so with this first response back to the client, it tries BOTH cookies and URL rewriting.

Now imagine the next request from the same client has session ID append to the request URL, and also have session ID cookie. Now the container ignores calls the response.encodeURL().

If the client won't accept cookies, in every request, container cannot find session ID cookie, so it creates a new session as well as encodes response URL.

How to encode redirect URLs?

You might have scenarios where you want to redirect the request to a different URL, but you still want to use a session. There's a special URL encoding method just for that.

response.encodeRedirectURL("/speakincs.do");

How to destroy inactive sessions?

calling session.invalidate() method destroys the session. The container kills the session, if a session times out. you can configure session time out in the DD.


   15

here "15" is in minutes.

What will happen, if you try to get an attribute after session becomes invalid?

 You will get a runtime exception i.e IllegalStateException, because you can't get an attribute after the session becomes invalid.

Once the session is destroyed, calling any methods on it would results "IllegalStateException".


















 

0 comments:

Post a Comment

Note: only a member of this blog may post a comment.