This is the fifth article in the series of Java Web Application, you might want to check out earlier four articles too. java
In this tutorial, we will look into servlet listener, benefits of 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 andServletRequest. mysql
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. web
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. sql
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. apache
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. cookie
Servlet API provides following event objects. java-web
Servlet API provides following Listener interfaces. session
We can use @WebListener annotation to declare a class as Listener, however the class should implement one or more of the Listener interfaces. app
We can define listener in web.xml as: async
1
2
3
|
<listener>
<listener-class>com.journaldev.listener.AppContextListener</listener-class>
</listener>
|
Let’s create a simple web application to see listeners 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.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
<?xmlversion="1.0"encoding="UTF-8"?>
<web-appxmlns:xsi="
http://www.w3.org/2001/XMLSchema-instance"xmlns="
http://java.sun.com/xml/ns/javaee"xsi:schemaLocation="
http://java.sun.com/xml/ns/javaee
http://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.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
packagecom.journaldev.db;
importjava.sql.Connection;
publicclassDBConnectionManager {
privateString dbURL;
privateString user;
privateString password;
privateConnection con;
publicDBConnectionManager(String url, String u, String p){
this.dbURL=url;
this.user=u;
this.password=p;
//create db connection now
}
publicConnection getConnection(){
returnthis.con;
}
publicvoidcloseConnection(){
//close DB connection here
}
}
|
MyServlet: A simple servlet class where I will work with session, attributes etc.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
packagecom.journaldev.servlet;
importjava.io.IOException;
importjava.io.PrintWriter;
importjavax.servlet.ServletContext;
importjavax.servlet.ServletException;
importjavax.servlet.annotation.WebServlet;
importjavax.servlet.http.HttpServlet;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
importjavax.servlet.http.HttpSession;
@WebServlet("/MyServlet")
publicclassMyServletextendsHttpServlet {
privatestaticfinallongserialVersionUID = 1L;
protectedvoiddoGet(HttpServletRequest request, HttpServletResponse response)throwsServletException, 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.
We will read servlet context init parameters to create the DBConnectionManager object and set it as attribute to the ServletContext object.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
packagecom.journaldev.listener;
importjavax.servlet.ServletContext;
importjavax.servlet.ServletContextEvent;
importjavax.servlet.ServletContextListener;
importjavax.servlet.annotation.WebListener;
importcom.journaldev.db.DBConnectionManager;
@WebListener
publicclassAppContextListenerimplementsServletContextListener {
publicvoidcontextInitialized(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 =newDBConnectionManager(url, u, p);
ctx.setAttribute("DBManager", dbManager);
System.out.println("Database connection initialized for Application.");
}
publicvoidcontextDestroyed(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.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
packagecom.journaldev.listener;
importjavax.servlet.ServletContextAttributeEvent;
importjavax.servlet.ServletContextAttributeListener;
importjavax.servlet.annotation.WebListener;
@WebListener
publicclassAppContextAttributeListenerimplementsServletContextAttributeListener {
publicvoidattributeAdded(ServletContextAttributeEvent servletContextAttributeEvent) {
System.out.println("ServletContext attribute added::{"+servletContextAttributeEvent.getName()+","+servletContextAttributeEvent.getValue()+"}");
}
publicvoidattributeReplaced(ServletContextAttributeEvent servletContextAttributeEvent) {
System.out.println("ServletContext attribute replaced::{"+servletContextAttributeEvent.getName()+","+servletContextAttributeEvent.getValue()+"}");
}
publicvoidattributeRemoved(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.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
packagecom.journaldev.listener;
importjavax.servlet.annotation.WebListener;
importjavax.servlet.http.HttpSessionEvent;
importjavax.servlet.http.HttpSessionListener;
@WebListener
publicclassMySessionListenerimplementsHttpSessionListener {
publicvoidsessionCreated(HttpSessionEvent sessionEvent) {
System.out.println("Session Created:: ID="+sessionEvent.getSession().getId());
}
publicvoidsessionDestroyed(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.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
packagecom.journaldev.listener;
importjavax.servlet.ServletRequest;
importjavax.servlet.ServletRequestEvent;
importjavax.servlet.ServletRequestListener;
importjavax.servlet.annotation.WebListener;
@WebListener
publicclassMyServletRequestListenerimplementsServletRequestListener {
publicvoidrequestDestroyed(ServletRequestEvent servletRequestEvent) {
ServletRequest servletRequest = servletRequestEvent.getServletRequest();
System.out.println("ServletRequest destroyed. Remote IP="+servletRequest.getRemoteAddr());
}
publicvoidrequestInitialized(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 URLhttp://localhost:8080/ServletListenerExample/MyServlet, we will see following logs in the server log file.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
ServletContext attribute added::{DBManager,com.journaldev.db.DBConnectionManager@4def3d1b}
Database connection initializedforApplication.
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 closedforApplication.
|
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.
Please show your love by sharing or comments.