Why do we need request.getSession(true)? - servlets

When I first started learning J2EE, I was told that, we need to call request.getSession(true) to create a new session. But when I started testing HttpSessionListener, I found that the servlet container will create a HttpSession as soon as it receives a Http request from the client - before I explicitly try to create any session. Is the servlet container implicitly calling request.getSession() or request.getSessioin(true) to create a new session from me?
The only scenario where I found the getSession(true) to be useful is when I want to explicitly invalidate the existing session and create a new one. Is this the only real world scenario or are there any other examples?

But when I started testing HttpSessionListener, I found that the servlet container will create a HttpSession as soon as it receives a Http request from the client - before I explicitly try to create any session
I don't know how you tested it, but unfortunately it is not true. Try to create very simple servlet and put there:
System.out.println("Session: " + request.getSession(false));
you will see that session is null. Container doesn't create sessions, if it is not requested by your application.
You probably got that impression testing jsp pages, or some framework, which by default create session. But this can also be disabled using <%# page session="false" %>, if your page doesn't need session.
And regarding need of request.getSession(true) - you could say it is not needed as request.getSession() does exactly the same, however request.getSession(false) is needed to check, if there is a valid session associated with request.

Related

What's the difference between HttpSession object and HttpContext object?

I am learning Servlet. But don't understand the major difference between HttpSession object and HttpContext object ? As both are used to keep track of the user. But I don't understand , are both of them being accessible across the user or servlet ?
Can anyone provide me an example for this, so I can have clear understanding of it...
Request - Normally used for passing data from jsp to your servlet when you submit the form. When you get redirected to another jsp, your request dies. ie: this attribute lives per user request.please note that http is stateless protocol.so the server will treat every http request as a new request.
Session -session object is basically used to store the values in the session.the data will be preserved until the user terminates the program or closes the browser.Good example will be for storing user credentials. once user is authenticated, Sometimes you may want to check if the user has right access to do on some database operations like add/delete/edit. Once user closes the browser or the session goes idle for x amount minutes (depending on your server setup), the session dies and all info in it will be gone.
Context -context object can be used for multiple users and across multiple browsers.
If it is application specific, consider using context.
If it is user specific, consider using session.
If it is request specific (ex: jsp form submission), consider using request.
Hope this helps.

Webmethod authentication not passed

I'm new to this AJAX approach when you're not supposed to use UpdatePanel but rather go with WebMethods and WebServices. My main problem is authentication.
When page is entered or postback request is created, everything works fine. Authentication is passed correctly and I can access Thread.CurrentPrincipal.Identity and get my user identity object from there.
However this changes when I try to call WebMethod on my page. Call is passed correctly to server and everything seems to work just fine until i try to get user identity from thread. Then I get just Anonymous user instead of real one. Enabling session on webmethod didn't seem to help much.
Any ideas what might cause this problem and how to solve it? Someone mentioned that authentication cookie needs to be passed along with the request, but how am I supposed to do it?
Any help will be appreciated.
Edit:
Some clarification and code:
My application is written in standard asp.net. After some deeper research in legacy code I've found out, that all authentications are done in some base class from wchich all other pages inherit. Each time page is loaded, user principal are obtained from HttpContext.Current.Session("..."). I think this is far from good solution, but I'll need to stick with it right now. Problem was, WebMethod is not firing whole page lifecycle since it's static. I've fixed it right now by calling method that obtains user data from session.
I would like to get some ideas how this could be created correctly and what problems might be result of session based authentication.
PageMethods.SomeMethod(parameter, SuccessDelegate, FailureDelegate);
This is how I'm calling WebMethods right now. I assume it's passing all required cookies, am I right?
It depends on how you're calling the method and in what manner?
Jquery for instance with its Post method should push all cookies (including your FormsAuth / Session cookie) up with the request that should still authenticate as appropriate. Bare metal techniques might be making lightweight calls that simply do not push the cookie up...One way to monitor this is by using Fiddler to observe the request and a browser based development plugin like Firebug and see what is occuring and amend your JS code as appropriate.
Personally, if you are starting a brand new project and there is no pressing need to expose your services beyond your web application then I would suggest looking at ASP.NET MVC where you can make Jquery / client-side up to the controller and get your authentication wrapped up for free. I've recently created something simliar using WCF JSON endpoints and some inevitable pain, I then saw MVC and kinda kicked myself...
As noted in comment above, the issue lies in legacy code that handles users. It is needed to make call to special function that assigns appropriate user data to handling thread. Not a best solution, but that's how it sometimes is with legacy code. What you gonna do?

How to insert the username into MDC for the entire web request

I am trying to use a Mapped Diagnostic Context to add the username of the user making a page request to all relevant logging statements. However I have tried three different ways to make it work without success:
Pushing the username into the MDC after login and removing after logout. This method ends up mixing up which logging statement came from which user.
Using a ServletFilter to push the username into the MDC on each page load and pop it back off as the request ends. This only catches some of the data and only in Spring security layer.
Using a AOP #Around interceptor in front of all the Controller methods flat out didn't work.
Does anyone have any suggestions on how to make this happen?
What were the problems with MDC? What do you mean by Spring security layer? I used this approach in one web application and it worked well. Because MDC is bound to thread, all logging statements coming from this thread will have username set, i.e. service and repository layer as well.
Of course if some users are served from using threads (e.g. servlet 3.0 asynchronous processing, JMS listeners, executors), you will need the other way of injecting username to MDC in pooled threads.
Also see my answer here.

HttpSession Session ID different to FlexSession ID

I have a Flex application which is served via a JSP page. In this page I output the session ID using HttpSession when the page is loaded:
System.out.println("Session ID: " + session.getId());
In a very simple remote object hosted in BlazeDS (called from the flex application using an AMF Channel and standard RemoteObject functionality) I also output the session ID but this time using FlexSession (which as I understand is supposed to wrap around HttpSession).
System.out.println("FlexSession ID: " + FlexContext.getFlexSession().getId());
I would expect both IDs to be the same but this is not the case. The session IDs differ which is causing problems as there is data stored in the HttpSession which I need to be able to access from my remote objects within BlazeDS.
I've exhausted the reading material on BlazeDS and FlexClient/FlexSession/FlexContext but can't see why the FlexSession is not being linked to the HttpSession. Any pointers greatly appreciated.
I feel I must be missing something fundemental here, am I accessing the
I do not think that it is related to the FlashPlayer..is more related to the concept of FlexSession and how BlazeDS/LCDS works. For example you can have an active session even when not using the http channels - when using NIO/RTMP you are bypassing the application server and the http protocol. So it make sense to have an abstract class FlexSession with various implementations.
However when using BlazeDS FlexSession will wrap an HttpSession object internally, and removeAttribute/getAttribute/setAttribute are in fact calling the the same methods from the HttpSession object..so you can access all the data from the HttpSession. If not please provide more details.
However, it will not work when using RTMP channels(which exists only in LCDS by the way), you need to change your design in this case.
Thanks to both answers above I finally found the root cause and thought I'd share it on here.
The reason for differing session IDs was to do with the use of SSL for authentication and the use of AMF Channel rather than Secure AMF. Using the channel for the first time caused a new session to be created (hence the different ID) as the existing session related to the secure version of the site.
Silly configuration mistake but worth passing on - make sure that if using SSL that you're also using Secure AMF connecting to the secure endpoint rather than standard AMF or you'll run into the same session ID problems I faced.
Unfortunately this is just how the Flash player works. I have seen this same behavior many times.
The best solution I found was to establish the HTTP session and pass back the session ID. On the client side, you can then pass the session ID to the Flex application. You then send that ID from Flash to the server and use it to look up the existing session or establish a second session.
You will need to do something like this though, I have not been able to find a way to reliably get Flash to use the same session.

LazyInitializationException in ASP.NET app with NHibernate

Using NHibernate with ASP.NET 4.
I have had no issues retrieving objects, but I've just got to a point with nested objects that I can't figure out.
I am using lazy=true and when accessing a lazy-load collection I get the message:
Initializing[type#3]-failed to lazily initialize a collection of role: [type], no session or session was closed
Even if I call SessionFactory.OpenSession() immediately prior to the object being accessed, it makes no difference. I have also tried accessing the collection in a using ISession block to no luck.
Edit to add - I do have current_session_context_class = web set in web.config, and I am using CurrentSessionContext.Bind on BeginRequest.
Can anyone offer some advice?
Not an MVC app
I read this - don't know how accurate it is, and it is Hibernate:
http://opensource.atlassian.com/projects/hibernate/browse/HHH-2878
It says something about a bug in many-to-many relationships.
Here is my HBM mapping:
<bag name="Objects" table="ObjectInstance" cascade="all" lazy="true">
<key column="branchId" />
<many-to-many class="InventoryObjectInstance" column="objectInstanceId" />
</bag>
Does that happen after you perform some save/update operations? Where and when are you closing the session? To me, it sounds like you close the session right after save call or in some other method before the web page gets rendered. In other words, make sure you are using Open Session in View pattern and close the session only in the end of current web-request. You can also check out this post.
When object graphs are retrieved they keep a reference to the session that spawned them. They use that session for lazy loading of their properties. If the original session is closed, you will get this error (or one just like it) when trying to access them. Opening a new session will not help.
You can try to find where the original request session is being closed and stop that. Are you in the same request though? Failing that you can try to connect your object to a new session -- I think it is Session.Lock(YourObject). Alternatively you could retrieve the object again from the new session.
For some reason you are getting a new ISession when you call SessionFactory.OpenSession(). Is your first use of the session wrapping access to it in a using block? Why are you calling OpenSession again anyway -- what happened to the reference to the session?

Resources