I have seen that you can call getservletcontext() directly also and also like this req.getsession().getservletcontext() .
What is the difference between the two and which one should I use ? Is there any scenario based on which I should use one and not the other?
And by the way I am using web module 2.5
What is the difference between the two
There is no difference between the two, they are one and the same.
The method getServletContext() that you can call directly is only when your code is in a class that extends HttpServlet. That is because HttpServlet base class has this method defined (actually in the GenericServlet class that HttpServlet extends).
The ServletContext returned by req.getSession().getServletContext()is same as the one returned above.HttpSessioncontains a reference to theServletContext` that this session belongs to.
which one should I use? Is there any scenario based on which I should use one and not the other?
As long as your code is in the servlet class, you can use anything as both can be called.
Let's say (hypothetically) you call a method in your custom class from your servlet and pass the session object to it to work on some data in the session. This custom class doesn't extend servlet. You need a reference to the ServletContext in this custom class. Since you have a reference to the session, you can get access to the ServletContext using the method session.getServletContext().
Hope this is clear.
The Session variables are only saved for one browser and the Context variables can be used by all browsers in one session.
So if the user only uses one browser (as it is in most cases) there is no difference between them, but if you like to work from different browsers in one session better use the Context.
Related
I have a bunch of Servlets. I want all of them to instantiate a Logger, pretty much the exact same way.
Is there a proper (like a Main file) where I can bootsrap such code?
Currently what I do is created a subclass of the Servlet class, which does that in the init function and all the other Servltes inherit from it.
I don't know if it's a good idea what you are trying for the logger (i think you will lose some logger capacibilities), but well, if you want an unique instance of something in a servlet you should declare it and init it in the static way:
static final SomethingClear GLOBAL;
static{
// do tons of things to init
GLOBAL = ClassWithStaticFunc.gimmeGlobalLoaded();
}
An why is better this way? because there's another funny -or well, may be annoying :( - way to load a static (in the senses of uniqueness and that always will be an instance in memory) variable in a servlet:
Servlets dont have nothing like 'main'. They are unique instances which live in a servlet container, are instanciated by it, and its methods (doGet, doPost, doPut, doDelete) are executed by the servlet container on demand giving them request and response objects. So, in memory, there will be allways one and only one instance of each servlet, so any variable outside doGet, doPut, doDelete and doPost will be unique in memory. This was done this way in the beginings of the java-time in order to save memory...
And this is a funny way to merge sessions... :(
If you assing something to anything outside that methods in a servlet it will be assigned to all sessions of your application, and is not obvious and is not so easy to find...
So its better to mark them as static and final because they'll be always created (you have no access to objects construction) and there will be only one instance. It's not nice, but servlets are not nice...
I once did a unique servlet whose invoke my custom 'Servlets' using reflection (one object per petition, giving the name of my 'servlet' in the web.xml as initParam and setting the servlet-name always to the same servlet that was the instanciator of mines) to solve session merges and worked great.
In android there is a mechanism of ensuring that only one instance of a class is available to the whole application. This can be done by deriving that class from Application.
Can some thing similar be done in servlets? I want to initialize a class when the application is deployed. This class should have only one instance. So that what all the servlets can access it.
I came to know that you can store your data in the servlet context's hashmap. But I don't want to do that. I want to write my own class with its functions. How should this be done?
I think what you're after is simply a singleton.
This is best implemented by defining an enum with a single instance. (Note that enums allow you to have member functions just as classes.)
public enum YourSingleton {
INSTANCE;
// Your methods...
}
and then you access it as
YourSingleton.INSTANCE
So, create whatever class you want with its own functions or whatever you like, and put that in the ServletContext at startup. You can use a ServletContextListener to initialize and remove it. What's limiting about that?
Use singleton pattern so the first call to instance method (say YourClass.getInstance()) will create the instance and it will be reused across the application.
I am trying to create a simple service-like application. I am using the browser as the entry point, servlet as the receiver of the request and a couple of helper java classes. For example, I have user A go use the application at the same time as user B.
Now my question is, what happens to the helper classes when multiple users access the service? Do they get instantiated every time a user uses the application? 5 users, do they (helper classes) get instantiated 5 times, or for all the users, there is only one copy of everything?
That depends on when and where you instantiate those POJOs. If you are instantiating them on your doGet or doPost then you create new instances of those objects on every request(and discard them after the request has been responded to). Now if you are 'lazy instantiating' them onto a longer memory scope(session, etc) then you retain them longer(e.g. for session scope, throughout the life time of the session).
A simple answer is that whenever you are using the new YourClasseName(), you are instantiating a new object.
Since the servlet container allocates a thread for each new request for a single servlet (unless you had done some sort of special changes), then simply put, 5 users = 5 threads = 5 calls to construct your pojos. Meaning your objects get instantiated 5 times.
I think you need to go back and read about class instantiation and their life cycle in java first. And to be more specific to your situation, please provide code snippets. It will depend on how you instantiate your helper classes, 3 possibilities that I can think of:
1- Regular helper class
This is the case where you simply call Helper h = new Helper(); and you just call actions on your helper classes h.doHelp(param) - each time your Servlet call this, it creates new instance of the Helper class. Unless of course your helper class use any static variables.
2 - Singleton
When you implement your Helper class as a Singleton and your Servlet calls it the way Singleton are created, eg Helper h = Helper.getInstance() If you do it that way, then every request to the Servlet share the same instance of the Hepler class
3 - Static class
If your helper class are just using static methods, eg. Helper.doHelp(param); then there's also no sharing between the different request, unless of course your helper class use any static variables.
Your helper classes should be singletons, That way both the userA and userB will use the same instance instead of instantiating twice.
I understand that this is normally not done, and I've found a number of instances of this question around the web with answers of the sort: "Your design is wrong if you need to do this." Let me explain my goal.
I have a web app that at one site somehow caused one servlet's init() method to be called repeatedly. I don't know how this happened and I cannot repeat it. However, from a binary heap dump (caused by an out-of-memory exception), it is very clear from objects on the heap that a specific servlet's init() method got called about 10,000 times, as that is the only place these objects are created and there were 10,000+ instances of an object that is supposed to have no more than one instance.
Since I cannot reproduce what happened at this one site, I instead want to forcefully invoke init() many times on this servlet, preferably via a JSP file, so I can test before and after a fix is applied. Testing the "after" case is easy in theory because I can change the code to (for example) stick this servlet into the context so I can get it and repeatedly call init() to prove that there is no leak of this object. But this does not help me test the "before" case with the existing code.
I cannot just "(new MyServlet()).init()" in a JSP. This fails as the servlet is created with a null context and fails to initialize. By Tomcat 5.5, it seems that ServletContext.getServlets() always returns an empty Enumeration and that ServletContext.getServlet(String) always returns null.
It seems the easiest way to test is if I can somehow programmatically (preferably from a JSP) get access to the servlet instance in question, or alternately, programmatically add new mappings to that same servlet class, which might create new instances. (?)
You've already figured out that what you are attempting is highly out of the ordinary and far from a best practice so I won't go into any detail on that subject. Having said that, if you want to invoke MyServlet.init() many times on an instance of MyServlet running within Tomcat, you could subclass MyServlet, override the doGet() or doPost() method, add a loop that simply calls this.init(); 1000 times and then call the parent classes doGet()/doPost(). Edit WEB-INF/web.xml to use your subclass in place of MyServlet. Then just hit the servlet with your web browser and see init() called 1000 times prior to serving the page normally. And you haven't modified the original MyServlet class at all, keeping your before test pure.
You can create a servlet instance like any other class object. Get hold of the servlet config by overriding the method init(ServletConfig config). And create the servlet class instance as many as u want, and call init(ServletConfig config) on all those instances created.
servlets uses init() to initialize servlets status and destroy to clean up. Is there a special class name we need to put init() and destroy()? How does servlets know where to find these methods?
asp.net has a global.asax to handle similar thing in asp.net , servlets has a special class to do the same thing?
Thanks
Servlets will ultimately be a subclass of the javax.servlet.Servlet class, which defines those methods.
It should be in the same class as your Servlet class.
All servlets inherit this method from the base Servlet class. Unless you want to do some additional processing, the inherited method should be fine and you dont need to override this method in each of your servlets.
Servlets are deployed in the Container(Web Server/Application Server),That container will take care of initializing or destroying of servlets,and we dont have predefined classes to initialise and destroy for servlets,if we use particular class that means we are depending on that class(Tightly Coupling) thats not recomended.
Now we are using GenericServlet,and HttpServlet classes for that methods..once refer J2EE API and find this classes and methods in them..
The JVM which runs the Servlet, looks for those methods only in classes, which extend Servlet or HttpServlet.
Servlets are managed objects. This means that they are executed inside a container that manages their lifecycles (instantiates the servlets, call their relevant methods when it is appropiate, and releases them). The container (Tomcat, Glassfish, ...) knows when to call these methods at the right time because it is implemented that way, there is nothing special about that.
If the container had a bug, it could even call, say, destroy() at init time and init() at destroy time. That bug would be fixed quickly, though.