Method getServletContextName() returns the name of the "web application". That means, "ServletContext" is nothing but "web application". Ok.
API defines:
a ServletContextListener receives notifications about changes to the servlet context of the web application they are part of.
What does "servlet context" of the "web application" mean? What actually is "Context" in "ServletContext"?
The name is indeed, IMO, very badly chosen.
We must read ServletContext as "the general context of a servlet API based web application".
Whereas we must read ServletConfig (another standard class) as "The config of a servlet".
They should IMO have named ServletContext as "WebAppContext" or "ApplicationContext",
and ServletConfig as "ServletContext".
BTW, in JSP, the scope linked to a JspPage is named "page"; the scope linked to a HttpServletRequest is named "request"; the scope named to a HttpSession is named "session", and the scope linked to a ServletContext is named ... "application".
"Context" means.. context - it has contextual information and functionality for a particular web application:
application-wide parameters
application event listeners
metadata about the application
ServletContext is the context of a Java web application (because it uses servlets)
Context means web app here.
A ServletContextListener gets notified when a Web App is started or stopped. That way you can run tasks automatically that need to be run when the web app starts or stops.
A ServletContext is the runtime representation of the web application.
ServletContext implies Context or Runtime environment of servlet. Servlets runs in Servlet containers like tomcat. Servlet container creates and provides runtime environment for the servlet to get executed and it manages its lifecycle. It also holds other information, as :-
application-wide parameters
application event listeners
metadata about the application
ServletContext is interface that contain a set of methods to communicate with its own servlet container.
Context that stand as a one per web application on per jvm .
That allow servlets to gain access to the context for various parts of the server to communicate.
Life Cycle of ServletContext
Servlet container reads the DD (Deployment Descriptor – web.xml) and creates the name/value string pair for each when web application is getting started.
Container creates the new Instance of ServletContext.
Servlet container gives the ServletContext a reference to each name/value pair of the context init parameter.
Every servlet and JSP in the same web application will now has access to this ServletContext.
ServletConfig vs ServletContext
ServletContext is available to all servlet & jsp in web application while ServletConfig will be available only specific servlet.
Servlet config is one per servlet and Servlet context is one per web application
Related
I'm trying to get ServletContext in the class which is implementing EnvironmentPostProcessor. ServletContext is required to get the war filename. Based on war file name I get properties from a database and will set to properties to user later in the applications.
I'm not using Embedded Container but WildFly Server
public class ClEnvironment implements EnvironmentPostProcessor, ServletContextAware, ServletContextInitializer
But it's not working.
You can’t get the ServletContext in an EnvironmentPostProcessor. The post-processors are loaded from spring.factories very early in the application’s lifecycle. With an embedded servlet container that happens long before the container has been started and the ServletContext is available.
This may be an XY problem. Perhaps you could ask another question that explains what you are trying to do. There may be another way to do it that does not require access to the ServletContext in an environment post-processor.
I have a tomcat server running a webapp. In the webapp's startup, I'm setting few context parameters using an implemented class for interface ServletContextListener. The parameter that I am initializing here are a couple of connection objects for a database running on a different machine.
The doubt that i have is whether the connection objects that I created here are one for each instance (since tomcat creates one instance per client request), or one for the entire webapp itself?.
If it is one per webapp, then can the server handle large simultaneous requests (in the order of thousand request per second) to perform the CRUD operations on the database?.
ServletContext is created one per webApp. The server reads the web.xml file from the web app and creates a ServletContext based on the configuration you provide on web.xml. Once created it is shared between the components of the web app. If you have multiple webapp installed on your server, you will have multiple ServletContext - each for the web app.
For reference please have a look here
A webapp has only one instance of ServletContext and the atributes in ServletContext are application scoped.
Regarding you database connection, it's better to use connection pooling (DataSource) instead of adding Connection objects as attributes in ServletContext.
Not sure if you mean this but the requests are handled by Servlets and not ServletContext.
If your setting an attribute on the ServletContext the attribute will be scoped for the entire application.
From the Java EE 7 Spec:
There is one instance object of the ServletContext interface
associated with each Web application deployed into a container.
only one ServletContext is loaded irrespective of the number of requests made.
This is even the advantage of servlets over CGI.
Hope it helps.
When exactly a web container initialize a servlet?
Is it guaranteed that it does it at web container start up time?
Thanks.
No, it's not. First, the webapp itself is not guaranteed to be started when the container starts (that depends on the specific container configuration). And even if the webapp is started, the specification says:
Servlets are initialized either lazily at request processing time or eagerly during deployment. In the latter case, they are initialized in the order indicated by their load-on-startup elements.
When exactly a web container initialize a servlet?
Either at the time of loading the web application or on the first request to the servlet. This is configurable in web.xml using load-on-startup flag
Is it guaranteed that it does it at web container start up time?
Nothing is guranteed when it comes to the container. It depends how the contianer is written .The only way to request the container is through configurable param load-on-startup in in web.xml.
Depends on how you are defining and configuring your servlet.
You might find this clearly in docs
Initializing a Servlet
After the web container loads and instantiates the servlet class and before it delivers requests from clients, the web container initializes the servlet. To customize this process to allow the servlet to read persistent configuration data, initialize resources, and perform any other one-time activities, you override the init method of the Servlet interface. A servlet that cannot complete its initialization process should throw UnavailableException.
If you want to participate in that process ovveride init method of the Servlet interface and do the required stuff there.
Is HttpSession object available to all the applications that is running in the same java enterprise application server?
For my work, i have login application which does the authentication and then it will be forwarded to another application.In Second application, filter is added to prevent the direct access to the URL
ServletContext - gets only the context of the current webapplication.
What is the correct approach to handle this scenario?
The HttpSession objects are scoped at the application (or servlet context) level.
An excerpt from Java™ Servlet Specification:
HttpSession objects must be scoped at the application (or servlet
context) level. The underlying mechanism, such as the cookie used to
establish the session, can be the same for different contexts, but the
object referenced, including the attributes in that object, must never
be shared between contexts by the container.
To illustrate this requirement with an example: if a servlet uses the
RequestDispatcher to call a servlet in another Web application, any
sessions created for and visible to the servlet being called must be
different from those visible to the calling servlet.
An approach to handle this scenario:
You can get access to the resources available for one servlet context from the other by using servletContext.getContext("/otherWebappContext") method as below:
request.setAttribute("userToken", <token>);
RequestDispatcher requestDispatcher = getServletContext().getContext(
"/otherWebappContext").getRequestDispatcher("/resource");
requestDispatcher.forward(request, response);
But any session created for the servlet being called is different from that of the calling servlet. Once the request is forwarded to the second application, it can create a new session with the data received through the request attributes.
But for security reasons, servlet containers normally prevent these cross-context operations. So you need to change the default behavior. For example, in Tomcat 6 you need to set the crossContext attribute to "true" for <Context> element in TOMCAT_HOME/conf/context.xml file as below:
<?xml version='1.0' encoding='utf-8'?>
<Context crossContext="true">
<!-- Default set of monitored resources -->
<WatchedResource>WEB-INF/web.xml</WatchedResource>
</Context>
No HttpSession Object is not available to all the applications present in the same server.
To verify,
create 2 apps,
In one app use seesion.setAttribute("hello","hello");
Now run second app
if(session.getAttribute("hello")==null)
{
//some codes to check
}
else
{
//some codes to check
}
You will see if part will be executed
No HttpSession objects are not shared among applications. The standard way of sharing an information among different applications in a container is to use ServletContext. The only limitation with ServletContext is that if a web applicationa is distributed between multiple JVM this will not work because context info is within one JVM.
I'm far from an expert of the intricacies of Resource Injection, and of indeed DataSources in Java, but I generally understand the process of doing a lookup for a predefined JNDI resource to get a datasource from.
Using Resource Injection as an alternate method, the below syntax works:
#Resource(name="jdbc/Foo")
private javax.sql.DataSource con;
However, I am using this in a servlet and as such wondering, how long this injected connection object's value will exist? Presumably, as it's simply an object within the servlet, it will inject when the servlet is first instantiated and exist for the same duration as the servlet (assuming I don't manually change it). Is this correct? Or does the servlet re-inject the resource everytime the servlet is used?
Thanks
A servlet container only ever creates one instance of your servlet. The IoC container you're using will then instantiate and inject the DataSource, so the value in con will remain the same for the life of your servlet, ie. the life of the application.
As to the underlying connection the DataSource is trying to make will, that's up to your datasource.
it will inject when the servlet is first instantiated and exist for the same duration as the servlet
Correct.
Or does the servlet re-inject the resource everytime the servlet is used?
No, this couldn't be happening because each request is served by a different thread. It wouldn't be good if those threads would modify the fields of the servlet. Request processing methods of the servlet must not modify its fields.
Generally container managed resources are injected using #Resources annotation. And container managed resources live as long as the container is running ( unless your are not manually kill it or any exception happens). Several applications can use the same resource object, provided that they live in the same application server ecosystem (same application server or cluster or server domain). But servlets are managed by your applications and lives within the application's scope as long as your application is running! So in terms of life span, if you compare resources are longer living than servlets.
And yes you are right, if you inject resources to a servlet, the reference of the resource will remain from the creation of the servlet to the end of the servlet's life cycle. The injection is not related with, how you are using the servlet or the resource.
Hope, this answers your question, Thanks!