Java web application object dispatching - java

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.

Related

ServletContext parameters: are they per instance or per server?

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?

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.

Tomcat global variable

I was wondering if there is a global session concept in tomcat (à la PHP). Imagine a really vanilla webapp with a servlet that takes input via POST and dumps them into an object (ignore obvious security concerns). The index page then just displays all the input so far.
I would like to put this object into a global variable. I can go the static methods / singleton route but just wondering if tomcat supports global variables.
Thanks!
There is many context in the Servlet specifications:
Servlet or application context. This let you store object that can be shared across of all the application a for all the clients (browsers). The objects stored in this context are alive until the application is undeployed or the container (Tomcat) is shutted down
Session context. This let you store objects in the session of the client (browser session). Also this objects are alive until the session of the users expires
Request context. This let to you store objects across the different requests. The objest stored in the requests are alive until the request is completed
I hope this can help you.

What does "Context" in "ServletContext" mean?

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

Can an applet communicate with an instance of a servlet

I have an applet that communicates with a servlet using Http (Not sockets). Currently, each instance of the applet (i.e. when each applet is run by a different client on a different computer), all the instances communicate with the same servlet. What I want is that each instance of the applet communicate with different instances of the same servlet. Is this possible?
You don't want to have different instances of the same servlet in webapp's lifetime. The normal practice is to use the HttpSession to distinguish between clients. You need to pass the HttpSession#getId() as parameter to the applet in question:
<param name="jsessionid" value="${pageContext.session.id}">
Then, in the Applet connect the Servlet as follows:
String jsessionid = getParameter("jsessionid");
URL servlet = new URL(getCodeBase(), "servleturl;jsessionid=" + jsessionid);
URLConnection connection = servlet.openConnection();
// ...
Here servleturl obviously should match servlet's url-pattern in web.xml. You can alternatively also set a Cookie request header using URLConnection.setRequestProperty().
Finally, in the Servlet, to get and store client specific data, do as follows:
// Store:
request.getSession().setAttribute("data", data);
// Get:
Data data = (Data) request.getSession().getAttribute("data");
Hope this helps.
From your question it seems that your servlet contains state. Every applet will have a session with the servlet container which your servlet can access. You can create an object that holds the state per session and place that object as attribute in the session of the caller. This way the servlet container is free to share one servlet instance among many clients.
The usual way to handle instance-specific actions is to have information stored in the session scope made available by the servlet container, not by having information stored in the servlet itself.
For it to work, your applet must correctly send cookies or the JSESSIONID attribute as provided by the web container or the applet must request a instance specific URL inside the servlet.
I would suggest you familiarize yourself further with the Servlet API specification in order to learn more about what is available to you.
Also note that some application servers support the notion of "clients" which are programs invoked with code served from the application server which have direct access to the inside of the application server code. The actual communication is handled by libraries also provided by the applcation server so this is simple. Glassfish and Trifork can do this.

Categories