ServletContextListener is one of the many Servlet Listener we have. This is the fifth article in the series of Java Web Application, you might want to check out earlier four articles too.
In this tutorial, we will look into servlet listener, benefits of servlet listeners, some common tasks that we can do with listeners, servlet API listener interfaces and Event objects. In the end we will create a simple web project to show example of commonly used Listener implementation for ServletContext, Session and ServletRequest.
We know that using ServletContext
, we can create an attribute with application scope that all other servlets can access but we can initialize ServletContext init parameters as String only in deployment descriptor (web.xml). What if our application is database oriented and we want to set an attribute in ServletContext for Database Connection. If you application has a single entry point (user login), then you can do it in the first servlet request but if we have multiple entry points then doing it everywhere will result in a lot of code redundancy. Also if database is down or not configured properly, we won’t know until first client request comes to server. To handle these scenario, servlet API provides Listener interfaces that we can implement and configure to listen to an event and do certain operations. Event is occurrence of something, in web application world an event can be initialization of application, destroying an application, request from client, creating/destroying a session, attribute modification in session etc. Servlet API provides different types of Listener interfaces that we can implement and configure in web.xml to process something when a particular event occurs. For example, in above scenario we can create a Listener for the application startup event to read context init parameters and create a database connection and set it to context attribute for use by other resources.8. ### Servlet Listener Interfaces and Event Objects
Servlet API provides different kind of listeners for different types of Events. Listener interfaces declare methods to work with a group of similar events, for example we have ServletContext Listener to listen to startup and shutdown event of context. Every method in listener interface takes Event object as input. Event object works as a wrapper to provide specific object to the listeners. Servlet API provides following event objects.
Servlet API provides following Listener interfaces.
javax.servlet.AsyncListener - Listener that will be notified in the event that an asynchronous operation initiated on a ServletRequest to which the listener had been added has completed, timed out, or resulted in an error.
javax.servlet.ServletContextListener - Interface for receiving notification events about ServletContext lifecycle changes.
javax.servlet.ServletContextAttributeListener - Interface for receiving notification events about ServletContext attribute changes.
javax.servlet.ServletRequestListener - Interface for receiving notification events about requests coming into and going out of scope of a web application.
javax.servlet.ServletRequestAttributeListener - Interface for receiving notification events about ServletRequest attribute changes.
javax.servlet.http.HttpSessionListener - Interface for receiving notification events about HttpSession lifecycle changes.
javax.servlet.http.HttpSessionBindingListener - Causes an object to be notified when it is bound to or unbound from a session.
javax.servlet.http.HttpSessionAttributeListener - Interface for receiving notification events about HttpSession attribute changes.
javax.servlet.http.HttpSessionActivationListener - Objects that are bound to a session may listen to container events notifying them that sessions will be passivated and that session will be activated. A container that migrates session between VMs or persists sessions is required to notify all attributes bound to sessions implementing HttpSessionActivationListener.
We can use @WebListener annotation to declare a class as Listener, however the class should implement one or more of the Listener interfaces. We can define listener in web.xml as:
<listener>
<listener-class>
com.journaldev.listener.AppContextListener
</listener-class>
</listener>
Let’s create a simple web application to see servlet listener in action. We will create dynamic web project in Eclipse ServletListenerExample those project structure will look like below image. web.xml: In deployment descriptor, I will define some context init params and listener configuration.
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns="https://java.sun.com/xml/ns/javaee" xsi:schemaLocation="https://java.sun.com/xml/ns/javaee https://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>ServletListenerExample</display-name>
<context-param>
<param-name>DBUSER</param-name>
<param-value>pankaj</param-value>
</context-param>
<context-param>
<param-name>DBPWD</param-name>
<param-value>password</param-value>
</context-param>
<context-param>
<param-name>DBURL</param-name>
<param-value>jdbc:mysql://localhost/mysql_db</param-value>
</context-param>
<listener>
<listener-class>com.journaldev.listener.AppContextListener</listener-class>
</listener>
<listener>
<listener-class>com.journaldev.listener.AppContextAttributeListener</listener-class>
</listener>
<listener>
<listener-class>com.journaldev.listener.MySessionListener</listener-class>
</listener>
<listener>
<listener-class>com.journaldev.listener.MyServletRequestListener</listener-class>
</listener>
</web-app>
DBConnectionManager: This is the class for database connectivity, for simplicity I am not providing code for actual database connection. We will set this object as attribute to servlet context.
package com.journaldev.db;
import java.sql.Connection;
public class DBConnectionManager {
private String dbURL;
private String user;
private String password;
private Connection con;
public DBConnectionManager(String url, String u, String p){
this.dbURL=url;
this.user=u;
this.password=p;
//create db connection now
}
public Connection getConnection(){
return this.con;
}
public void closeConnection(){
//close DB connection here
}
}
MyServlet: A simple servlet class where I will work with session, attributes etc.
package com.journaldev.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
@WebServlet("/MyServlet")
public class MyServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext ctx = request.getServletContext();
ctx.setAttribute("User", "Pankaj");
String user = (String) ctx.getAttribute("User");
ctx.removeAttribute("User");
HttpSession session = request.getSession();
session.invalidate();
PrintWriter out = response.getWriter();
out.write("Hi "+user);
}
}
Now we will implement listener classes, I am providing sample listener classes for commonly used listeners - ServletContextListener, ServletContextAttributeListener, ServletRequestListener and HttpSessionListener.27. ## ServletContextListener
We will read servlet context init parameters to create the DBConnectionManager object and set it as attribute to the ServletContext object.
package com.journaldev.listener;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import com.journaldev.db.DBConnectionManager;
@WebListener
public class AppContextListener implements ServletContextListener {
public void contextInitialized(ServletContextEvent servletContextEvent) {
ServletContext ctx = servletContextEvent.getServletContext();
String url = ctx.getInitParameter("DBURL");
String u = ctx.getInitParameter("DBUSER");
String p = ctx.getInitParameter("DBPWD");
//create database connection from init parameters and set it to context
DBConnectionManager dbManager = new DBConnectionManager(url, u, p);
ctx.setAttribute("DBManager", dbManager);
System.out.println("Database connection initialized for Application.");
}
public void contextDestroyed(ServletContextEvent servletContextEvent) {
ServletContext ctx = servletContextEvent.getServletContext();
DBConnectionManager dbManager = (DBConnectionManager) ctx.getAttribute("DBManager");
dbManager.closeConnection();
System.out.println("Database connection closed for Application.");
}
}
A simple implementation to log the event when attribute is added, removed or replaced in servlet context.
package com.journaldev.listener;
import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;
import javax.servlet.annotation.WebListener;
@WebListener
public class AppContextAttributeListener implements ServletContextAttributeListener {
public void attributeAdded(ServletContextAttributeEvent servletContextAttributeEvent) {
System.out.println("ServletContext attribute added::{"+servletContextAttributeEvent.getName()+","+servletContextAttributeEvent.getValue()+"}");
}
public void attributeReplaced(ServletContextAttributeEvent servletContextAttributeEvent) {
System.out.println("ServletContext attribute replaced::{"+servletContextAttributeEvent.getName()+","+servletContextAttributeEvent.getValue()+"}");
}
public void attributeRemoved(ServletContextAttributeEvent servletContextAttributeEvent) {
System.out.println("ServletContext attribute removed::{"+servletContextAttributeEvent.getName()+","+servletContextAttributeEvent.getValue()+"}");
}
}
A simple implementation to log the event when session is created or destroyed.
package com.journaldev.listener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
@WebListener
public class MySessionListener implements HttpSessionListener {
public void sessionCreated(HttpSessionEvent sessionEvent) {
System.out.println("Session Created:: ID="+sessionEvent.getSession().getId());
}
public void sessionDestroyed(HttpSessionEvent sessionEvent) {
System.out.println("Session Destroyed:: ID="+sessionEvent.getSession().getId());
}
}
A simple implementation of ServletRequestListener interface to log the ServletRequest IP address when request is initialized and destroyed.
package com.journaldev.listener;
import javax.servlet.ServletRequest;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.annotation.WebListener;
@WebListener
public class MyServletRequestListener implements ServletRequestListener {
public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
ServletRequest servletRequest = servletRequestEvent.getServletRequest();
System.out.println("ServletRequest destroyed. Remote IP="+servletRequest.getRemoteAddr());
}
public void requestInitialized(ServletRequestEvent servletRequestEvent) {
ServletRequest servletRequest = servletRequestEvent.getServletRequest();
System.out.println("ServletRequest initialized. Remote IP="+servletRequest.getRemoteAddr());
}
}
Now when we will deploy our application and access MyServlet in browser with URL https://localhost:8080/ServletListenerExample/MyServlet
, we will see following logs in the server log file.
ServletContext attribute added::{DBManager,com.journaldev.db.DBConnectionManager@4def3d1b}
Database connection initialized for Application.
ServletContext attribute added::{org.apache.jasper.compiler.TldLocationsCache,org.apache.jasper.compiler.TldLocationsCache@1594df96}
ServletRequest initialized. Remote IP=0:0:0:0:0:0:0:1%0
ServletContext attribute added::{User,Pankaj}
ServletContext attribute removed::{User,Pankaj}
Session Created:: ID=8805E7AE4CCCF98AFD60142A6B300CD6
Session Destroyed:: ID=8805E7AE4CCCF98AFD60142A6B300CD6
ServletRequest destroyed. Remote IP=0:0:0:0:0:0:0:1%0
ServletRequest initialized. Remote IP=0:0:0:0:0:0:0:1%0
ServletContext attribute added::{User,Pankaj}
ServletContext attribute removed::{User,Pankaj}
Session Created:: ID=88A7A1388AB96F611840886012A4475F
Session Destroyed:: ID=88A7A1388AB96F611840886012A4475F
ServletRequest destroyed. Remote IP=0:0:0:0:0:0:0:1%0
Database connection closed for Application.
Notice the sequence of logs and it’s in the order of execution. The last log will appear when you will shutdown the application or shutdown the container.
Thats all for listener in servlet, we will look into cookies and some common servlet examples next. You can download the project from below link and play around with it to learn more.
Download Servlet Listener Example Project
Check out next article in the series about Cookies in Servlet.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.
Can we create our own by extending EventObject and process that with our own listeners.
- dabbara venkatesh
Hi Can we set the value in web.xml file.
- Shyam
I downloaded and imported this project but when I am trying to run it on server only DBManager is invoked but the other servlet are not . please clarify whats missing here. Console logs are as : Jan 28, 2020 3:46:42 PM org.apache.catalina.startup.VersionLoggerListener log INFO: Server version name: Apache Tomcat/9.0.30 Jan 28, 2020 3:46:42 PM org.apache.catalina.startup.VersionLoggerListener log INFO: Server built: Dec 7 2019 16:42:04 UTC Jan 28, 2020 3:46:42 PM org.apache.catalina.startup.VersionLoggerListener log INFO: Server version number: 9.0.30.0 Jan 28, 2020 3:46:42 PM org.apache.catalina.startup.VersionLoggerListener log INFO: OS Name: Windows 10 Jan 28, 2020 3:46:42 PM org.apache.catalina.startup.VersionLoggerListener log INFO: OS Version: 10.0 Jan 28, 2020 3:46:42 PM org.apache.catalina.startup.VersionLoggerListener log INFO: Architecture: amd64 Jan 28, 2020 3:46:42 PM org.apache.catalina.startup.VersionLoggerListener log INFO: Java Home: C:\Program Files\Java\jre1.8.0_144 Jan 28, 2020 3:46:42 PM org.apache.catalina.startup.VersionLoggerListener log INFO: JVM Version: 1.8.0_144-b01 Jan 28, 2020 3:46:42 PM org.apache.catalina.startup.VersionLoggerListener log INFO: JVM Vendor: Oracle Corporation Jan 28, 2020 3:46:42 PM org.apache.catalina.startup.VersionLoggerListener log INFO: CATALINA_BASE: D:\workspace_adp_23Jan\.metadata\.plugins\org.eclipse.wst.server.core\tmp1 Jan 28, 2020 3:46:42 PM org.apache.catalina.startup.VersionLoggerListener log INFO: CATALINA_HOME: D:\Softwares\apache-tomcat-9.0.30 Jan 28, 2020 3:46:42 PM org.apache.catalina.startup.VersionLoggerListener log INFO: Command line argument: -Dcatalina.base=D:\workspace_adp_23Jan\.metadata\.plugins\org.eclipse.wst.server.core\tmp1 Jan 28, 2020 3:46:42 PM org.apache.catalina.startup.VersionLoggerListener log INFO: Command line argument: -Dcatalina.home=D:\Softwares\apache-tomcat-9.0.30 Jan 28, 2020 3:46:42 PM org.apache.catalina.startup.VersionLoggerListener log INFO: Command line argument: -Dwtp.deploy=D:\workspace_adp_23Jan\.metadata\.plugins\org.eclipse.wst.server.core\tmp1\wtpwebapps Jan 28, 2020 3:46:42 PM org.apache.catalina.startup.VersionLoggerListener log INFO: Command line argument: -Djava.endorsed.dirs=D:\Softwares\apache-tomcat-9.0.30\endorsed Jan 28, 2020 3:46:42 PM org.apache.catalina.startup.VersionLoggerListener log INFO: Command line argument: -Dfile.encoding=Cp1252 Jan 28, 2020 3:46:42 PM org.apache.catalina.core.AprLifecycleListener lifecycleEvent INFO: Loaded APR based Apache Tomcat Native library [1.2.23] using APR version [1.7.0]. Jan 28, 2020 3:46:42 PM org.apache.catalina.core.AprLifecycleListener lifecycleEvent INFO: APR capabilities: IPv6 [true], sendfile [true], accept filters [false], random [true]. Jan 28, 2020 3:46:42 PM org.apache.catalina.core.AprLifecycleListener lifecycleEvent INFO: APR/OpenSSL configuration: useAprConnector [false], useOpenSSL [true] Jan 28, 2020 3:46:42 PM org.apache.catalina.core.AprLifecycleListener initializeSSL INFO: OpenSSL successfully initialized [OpenSSL 1.1.1c 28 May 2019] Jan 28, 2020 3:46:43 PM org.apache.coyote.AbstractProtocol init INFO: Initializing ProtocolHandler [“http-nio-8080”] Jan 28, 2020 3:46:43 PM org.apache.coyote.AbstractProtocol init INFO: Initializing ProtocolHandler [“ajp-nio-8009”] Jan 28, 2020 3:46:43 PM org.apache.catalina.startup.Catalina load INFO: Server initialization in [1,509] milliseconds Jan 28, 2020 3:46:43 PM org.apache.catalina.core.StandardService startInternal INFO: Starting service [Catalina] Jan 28, 2020 3:46:43 PM org.apache.catalina.core.StandardEngine startInternal INFO: Starting Servlet engine: [Apache Tomcat/9.0.30] Jan 28, 2020 3:46:48 PM org.apache.jasper.servlet.TldScanner scanJars INFO: At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time. Jan 28, 2020 3:46:52 PM org.apache.jasper.servlet.TldScanner scanJars INFO: At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time. ServletContext attribute added::{DBManager,com.journaldev.db.DBConnectionManager@78698291} Database connection initialized for Application. Jan 28, 2020 3:46:52 PM org.apache.coyote.AbstractProtocol start INFO: Starting ProtocolHandler [“http-nio-8080”] Jan 28, 2020 3:46:52 PM org.apache.coyote.AbstractProtocol start INFO: Starting ProtocolHandler [“ajp-nio-8009”] Jan 28, 2020 3:46:52 PM org.apache.catalina.startup.Catalina start INFO: Server startup in [9,494] milliseconds ServletRequest initialized. Remote IP=127.0.0.1 ServletRequest destroyed. Remote IP=127.0.0.1
- shweta
Console for the same are as : Jan 28, 2020 3:46:42 PM org.apache.catalina.startup.VersionLoggerListener log INFO: Server version name: Apache Tomcat/9.0.30 Jan 28, 2020 3:46:42 PM org.apache.catalina.startup.VersionLoggerListener log INFO: Server built: Dec 7 2019 16:42:04 UTC Jan 28, 2020 3:46:42 PM org.apache.catalina.startup.VersionLoggerListener log INFO: Server version number: 9.0.30.0 Jan 28, 2020 3:46:42 PM org.apache.catalina.startup.VersionLoggerListener log INFO: OS Name: Windows 10 Jan 28, 2020 3:46:42 PM org.apache.catalina.startup.VersionLoggerListener log INFO: OS Version: 10.0 Jan 28, 2020 3:46:42 PM org.apache.catalina.startup.VersionLoggerListener log INFO: Architecture: amd64 Jan 28, 2020 3:46:42 PM org.apache.catalina.startup.VersionLoggerListener log INFO: Java Home: C:\Program Files\Java\jre1.8.0_144 Jan 28, 2020 3:46:42 PM org.apache.catalina.startup.VersionLoggerListener log INFO: JVM Version: 1.8.0_144-b01 Jan 28, 2020 3:46:42 PM org.apache.catalina.startup.VersionLoggerListener log INFO: JVM Vendor: Oracle Corporation Jan 28, 2020 3:46:42 PM org.apache.catalina.startup.VersionLoggerListener log INFO: CATALINA_BASE: D:\workspace_adp_23Jan\.metadata\.plugins\org.eclipse.wst.server.core\tmp1 Jan 28, 2020 3:46:42 PM org.apache.catalina.startup.VersionLoggerListener log INFO: CATALINA_HOME: D:\Softwares\apache-tomcat-9.0.30 Jan 28, 2020 3:46:42 PM org.apache.catalina.startup.VersionLoggerListener log INFO: Command line argument: -Dcatalina.base=D:\workspace_adp_23Jan\.metadata\.plugins\org.eclipse.wst.server.core\tmp1 Jan 28, 2020 3:46:42 PM org.apache.catalina.startup.VersionLoggerListener log INFO: Command line argument: -Dcatalina.home=D:\Softwares\apache-tomcat-9.0.30 Jan 28, 2020 3:46:42 PM org.apache.catalina.startup.VersionLoggerListener log INFO: Command line argument: -Dwtp.deploy=D:\workspace_adp_23Jan\.metadata\.plugins\org.eclipse.wst.server.core\tmp1\wtpwebapps Jan 28, 2020 3:46:42 PM org.apache.catalina.startup.VersionLoggerListener log INFO: Command line argument: -Djava.endorsed.dirs=D:\Softwares\apache-tomcat-9.0.30\endorsed Jan 28, 2020 3:46:42 PM org.apache.catalina.startup.VersionLoggerListener log INFO: Command line argument: -Dfile.encoding=Cp1252 Jan 28, 2020 3:46:42 PM org.apache.catalina.core.AprLifecycleListener lifecycleEvent INFO: Loaded APR based Apache Tomcat Native library [1.2.23] using APR version [1.7.0]. Jan 28, 2020 3:46:42 PM org.apache.catalina.core.AprLifecycleListener lifecycleEvent INFO: APR capabilities: IPv6 [true], sendfile [true], accept filters [false], random [true]. Jan 28, 2020 3:46:42 PM org.apache.catalina.core.AprLifecycleListener lifecycleEvent INFO: APR/OpenSSL configuration: useAprConnector [false], useOpenSSL [true] Jan 28, 2020 3:46:42 PM org.apache.catalina.core.AprLifecycleListener initializeSSL INFO: OpenSSL successfully initialized [OpenSSL 1.1.1c 28 May 2019] Jan 28, 2020 3:46:43 PM org.apache.coyote.AbstractProtocol init INFO: Initializing ProtocolHandler [“http-nio-8080”] Jan 28, 2020 3:46:43 PM org.apache.coyote.AbstractProtocol init INFO: Initializing ProtocolHandler [“ajp-nio-8009”] Jan 28, 2020 3:46:43 PM org.apache.catalina.startup.Catalina load INFO: Server initialization in [1,509] milliseconds Jan 28, 2020 3:46:43 PM org.apache.catalina.core.StandardService startInternal INFO: Starting service [Catalina] Jan 28, 2020 3:46:43 PM org.apache.catalina.core.StandardEngine startInternal INFO: Starting Servlet engine: [Apache Tomcat/9.0.30] Jan 28, 2020 3:46:48 PM org.apache.jasper.servlet.TldScanner scanJars INFO: At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time. Jan 28, 2020 3:46:52 PM org.apache.jasper.servlet.TldScanner scanJars INFO: At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time. ServletContext attribute added::{DBManager,com.journaldev.db.DBConnectionManager@78698291} Database connection initialized for Application. Jan 28, 2020 3:46:52 PM org.apache.coyote.AbstractProtocol start INFO: Starting ProtocolHandler [“http-nio-8080”] Jan 28, 2020 3:46:52 PM org.apache.coyote.AbstractProtocol start INFO: Starting ProtocolHandler [“ajp-nio-8009”] Jan 28, 2020 3:46:52 PM org.apache.catalina.startup.Catalina start INFO: Server startup in [9,494] milliseconds ServletRequest initialized. Remote IP=127.0.0.1 ServletRequest destroyed. Remote IP=127.0.0.1
- shweta
Extremely useful. Thank you so much,
- Vikas
Thank You very much sir for creating and sharing this wonderful tutorials Keep Making and help others
- Gopinath Ghanghao
What is the real or practical use of listeners.
- Anju boura
Hi I have created an AppContextListener in my class and I have added a line of code as follows in contextInitialized method: ValueHandler handler= new ValueHandler (); While building, I run mvn clean and mvn install commands. I get build successful message. But when I start my server, I get the following error: java.lang.NoClassDefFoundError: com/comp/proj/common/ValueHandler at com.comp.proj.context.AppContextListener.contextInitialized(AppContextListener.java:35) at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4939) at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5434) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1559) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1549) at java.util.concurrent.FutureTask.run(FutureTask.java:262) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) at java.lang.Thread.run(Thread.java:744) Please help me with this.
- Hemani
Can you please explain why each object has been created twice as in servlet class pankaj has been added and removed only once? ServletRequest initialized. Remote IP=0:0:0:0:0:0:0:1%0 ServletContext attribute added::{User,Pankaj} ServletContext attribute removed::{User,Pankaj} Session Created:: ID=8805E7AE4CCCF98AFD60142A6B300CD6 Session Destroyed:: ID=8805E7AE4CCCF98AFD60142A6B300CD6 ServletRequest destroyed. Remote IP=0:0:0:0:0:0:0:1%0 ServletRequest initialized. Remote IP=0:0:0:0:0:0:0:1%0 ServletContext attribute added::{User,Pankaj} ServletContext attribute removed::{User,Pankaj} Session Created:: ID=88A7A1388AB96F611840886012A4475F Session Destroyed:: ID=88A7A1388AB96F611840886012A4475F ServletRequest destroyed. Remote IP=0:0:0:0:0:0:0:1%0
- Vikram
Hi Pankaj Nice article…one doubt - will the listener executed in the same thread that handles request? Or is this done in a separate thread?
- Sreejesh