In PHP one is always able to access the current request or response from any part of their code. This concept is fundamental to PHP programming. Request data, response data, session data (etc) are always there!
This does not happen in Java Servlets! In order to have access to the HttpServletRequest, HttpServletResponse, HttpSession (etc) in your code you need to pass them around as function variables. This means that you cannot code a web framework that inherently "knows" about all these and removes the complexity of passing them around.
So, I have devised this solution:
Create anf register a ServletRequestListener.
Upon the requestInitialized event bind the current HttpServletRequest to the JNI context giving in the name of the current Thread (Thread.currentThread().getName());
Upon the requestDestroyed event unbind the above JNI resource to cleanup.
This way one has access to the current request/response from any place of their code, since they are always there in the JNI context and can be retrieved by providing the current thread's name.
All known servlet container implement the single-thread model for each request, so there is no way for the requests to get mixed up (of course one must not forget to clean them up).
Also the JNI resources of each web application are separated by default so there are no concerns of mixing them up or of security issues that could arise from one web application having access to the requests of the others.
Kinda twisted, but nice and simple...
What do you think?
I think some web frameworks (GWT, Axis) already do that, but in a much simpler way: by using a ThreadLocal static variable (or accessible from a singleton). Spring also has this possibility.
I'm not sure it works with all the containers, though. If the container uses non-blocking IO and reuses the same thread to handle multiple requests in parallel, it won't work anymore.
See Get the HttpServletRequest (request) object from Java code for a similar question (and its answers).
If you are worried about different requests getting messed up (and then think about "sub requests" like a model window), perhaps you'd rather think about using Seam? They use an abstraction called a "Session" to handle a LOT of the things that we developers try to hack around with other traditional web technology stacks. Seam is built on JSF just as an fyi. You don't have to use EJB 3 or Hibernate with it, but it does integrate nicely with both of those as well. Something to think about.
Related
For a pilot project I want to implement a custom and distributed user session. It seems the perfect spot for a ThreadLocal binding, carefully managed by a request filter.
Such user session is going to be available both in Servlet and non-Servlet environments. In Servlet environments, it should be independent of the presence or absence of any underlying javax.servlet.http.HttpSession (that is, it won't be allowed to create or use HttpSession objects).
Unfortunately I'm not able to find exhaustive information about how to handle this scenario in a Servlet 3.0 + environment configured for asynchronous operations. I understand (at least, I think...) that a javax.servlet.Filter should add a javax.servlet.AsyncListener to the current javax.servlet.AsyncContext, but some dedicated resources / real examples would be extremely helpful (mostly for showing some nuances I would certainly miss).
I am well aware of the ThreadLocal pitfalls, but their actual benefits (in such context) make me willing to find the proper way to implement them in such an asynchronous architecture (plus, passing a session reference to inner layers is not an option).
I heard a web application should be as stateless as possible. But it seems to me very hard to realize this often. For instance, what if I:
Process a request
Redirect the user to the start page
Want to display the result of the request?
If the result is a little bit more complex, then just a string which could be passed as a parameter (or I don't want to include that information via URL), then I cannot combine 2. and 3.
The only solution I can think of here is keeping the information as states in the Java program.
But that would break with the rule of a stateles web application, wouldn't it?
I heard a web application should be as stateless as possible
What? There is state everywhere in a web app, both in the client and on the server. Frameworks like Sproutcore/Ember even have components called State Managers to manage, um, the state.
The server maintains some state in a user's session (typically).
Did you hear that HTTP is stateless? That's another story, and completely true. Also, it can be a good idea to write server side components that don't share state, due to threading concerns. But neither of those points should be taken to imply that your application doesn't have state.
I have a web application running on Google App Engine (GAE) for JAVA. I'm authenticating the client at the Servlet layer but would like to make the client information available to my business and data layers without having to pass the client object through the arguments of every single function.
I'm considering setting up a "session" type object using ThreadLocal. That way any function can just say something like:
CurrentUser.getRoles();
Is this a good way to do this or is there something else that is a more accepted solution?
Thanks!
This will probably work and will be utterly convenient, but usually I try to avoid ThreadLocals for similar use cases as much as I can. Reasons:
You code just suddenly starts to depend on the fact that underlying container uses different threads for different users. If the container will start using NIO, different type of threads (e.g. green threads which would not be mapped into java.lang.Thread on some exotic JVM), etc. you will be out of luck.
ThreadLocals tend to be forgotten to be cleaned up after using them. So if your server will spike in usage and one of the users will put lots of stuff into 'cache', you might run out of RAM.
As a consequence of not cleaning up after a request, ThreadLocal can expose security vulnerability assuming the other user would jump unto the same thread.
Finally, I believe ThreadLocals were designed for environments where you have an absolute control over threads in your context, and this use case is just so far beyond.
Unfortunately I don't know much about GAE to suggest a viable alternative, sorry about that!
ThreadLocals are a completely accepted way to store such information. Besides us I also know from Alfresco that they do it.
If using Spring and Spring Security works for you then you can use the code I've built as part of jappstart for your authentication/authorization. This information is then available via Spring Security.
When do we need single threded model in webapp while designing web application in java.
The single-threaded model should almost always be avoided. (I'm assuming you're talking about the SingleThreadModel interface.) Basically it was introduced in an attempt to save people from having to think about concurrency, but it was a bad idea. Concurrency is inherent in web applications - introducing a bottleneck like the single threaded model is the wrong solution. The right solution is to educate developers about concurrency better, and introduce better building blocks for handling it.
The interface is deprecated as of the Java Servlet API 2.4, with this note:
Note that SingleThreadModel does not
solve all thread safety issues. For
example, session attributes and static
variables can still be accessed by
multiple requests on multiple threads
at the same time, even when
SingleThreadModel servlets are used.
It is recommended that a developer
take other means to resolve those
issues instead of implementing this
interface, such as avoiding the usage
of an instance variable or
synchronizing the block of the code
accessing those resources. This
interface is deprecated in Servlet API
version 2.4.
When your Servlet has state (which is a bad idea) and you want to prevent multiple requests in stepping on their own toes (or data).
I would recommend you avoid it because at some point you will mess something up. Also, performance drops like a brick.
The single thread model for servlets is used to signal that the servlet cannot handle multiple concurrent threads from client connections. Setting a servlet to the single threading model results in the servlet container (application server) to create a servlet instance per client.
It is best practice not to use the single thread model for servlets. Data kept per client connection is typically stored in the client Session object.
I am working on a web application in Java which gets data from servlets via AJAX calls.
This application features several page elements which get new data from the server at fairly rapid intervals.
With a lot of users, the demand on the server has a potential to get fairly high, so I am curious:
Which approach offers the best performance:
Many servlets (one for each type of data request)?
Or:
a single servlet that can handle all of the requests?
There is no performance reason to have more than one servlet. In a web application, only a single instance of a servlet class is instantitated, no matter how many requests. Requests are not serialized, they are handled concurrently, hence the need for your servlet to be thread safe.
The struts framework uses one servlet for everything in your app. Your stuff plugs into that one servlet. If it works for them, it will probably work for you.
One possible reason to have multiple services is that if you need to expand to multiple servers to handle the load in the future, it is easier to move a seperate service to it's own server than to do it "behind the scenes" if everything is comming out of one service.
That being said, there is extra maintinence overhead if you have multiple servlets, so it is a matter of balancing future flexibility with lower maintainability.
There is as such no performance enhancements in case you use multiple servlets since for each servlet request is handled in a separate thread, provided it is not single threaded.
But keeping modularity and separation of code, you can have multiple servlets.
Like Tony said, there really isn't a reason to use more than one servlet, unless you need to break up a complex Java Servlet class or perhaps implement an intercepting filter.
I'm sure you know that you can have multiple instances of the same servlet as long as you register different nodes in the web.xml file for your app -- ie, assuming you want to do that.
Other than that, from what I'm understanding, you might benefit from comet architecture -- http://en.wikipedia.org/wiki/Comet_(programming).
There are already some implementations of Comet on some servlet containers -- here's one look at how to use Ajax and Comet -- http://www.ibm.com/developerworks/java/library/j-jettydwr/. You should study before deciding on your architecture.
BR,
~A