博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Servlet Listener Example
阅读量:6442 次
发布时间:2019-06-23

本文共 15050 字,大约阅读时间需要 50 分钟。

hot3.png

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 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 ServletContextSession andServletRequest.

Why do we have Servlet Listener?

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.

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.

  1. javax.servlet.AsyncEvent – Event that gets fired when the asynchronous operation initiated on a ServletRequest (via a call to ServletRequest#startAsync or ServletRequest#startAsync(ServletRequest, ServletResponse)) has completed, timed out, or produced an error.
  2. javax.servlet.http.HttpSessionBindingEvent – Events of this type are either sent to an object that implements HttpSessionBindingListener when it is bound or unbound from a session, or to a HttpSessionAttributeListener that has been configured in the web.xml when any attribute is bound, unbound or replaced in a session.
    The session binds the object by a call to HttpSession.setAttribute and unbinds the object by a call to HttpSession.removeAttribute.
    We can use this event for cleanup activities when object is removed from session.
  3. javax.servlet.http.HttpSessionEvent – This is the class representing event notifications for changes to sessions within a web application.
  4. javax.servlet.ServletContextAttributeEvent – Event class for notifications about changes to the attributes of the ServletContext of a web application.
  5. javax.servlet.ServletContextEvent – This is the event class for notifications about changes to the servlet context of a web application.
  6. javax.servlet.ServletRequestEvent – Events of this kind indicate lifecycle events for a ServletRequest. The source of the event is the ServletContext of this web application.
  7. javax.servlet.ServletRequestAttributeEvent – This is the event class for notifications of changes to the attributes of the servlet request in an application.

Servlet API provides following Listener interfaces.

  1. 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.
  2. javax.servlet.ServletContextListener – Interface for receiving notification events about ServletContext lifecycle changes.
  3. javax.servlet.ServletContextAttributeListener – Interface for receiving notification events about ServletContext attribute changes.
  4. javax.servlet.ServletRequestListener – Interface for receiving notification events about requests coming into and going out of scope of a web application.
  5. javax.servlet.ServletRequestAttributeListener – Interface for receiving notification events about ServletRequest attribute changes.
  6. javax.servlet.http.HttpSessionListener – Interface for receiving notification events about HttpSession lifecycle changes.
  7. javax.servlet.http.HttpSessionBindingListener – Causes an object to be notified when it is bound to or unbound from a session.
  8. javax.servlet.http.HttpSessionAttributeListener – Interface for receiving notification events about HttpSession attribute changes.
  9. 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.

Servlet Listener Configuration

We can use @WebListener  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:

1
2
3
<listener>
    <listener-class>com.journaldev.listener.AppContextListener</listener-class>
</listener>

Servlet Listener Example

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.

web.xml
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=" "xmlns=" "xsi:schemaLocation=" "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.

DBConnectionManager.java
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.

MyServlet.java
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.

ServletContextListener implementation

We will read servlet context init parameters to create the DBConnectionManager object and set it as attribute to the ServletContext object.

AppContextListener.java
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.");
         
    }
     
}

ServletContextAttributeListener implementation

A simple implementation to log the event when attribute is added, removed or replaced in servlet context.

AppContextAttributeListener.java
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()+"}");
    }
     
}

HttpSessionListener implementation

A simple implementation to log the event when session is created or destroyed.

MySessionListener.java
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());
    }
     
}

ServletRequestListener implementation

A simple implementation of ServletRequestListener interface to log the ServletRequest IP address when request is initialized and destroyed.

MyServletRequestListener.java
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.

转载于:https://my.oschina.net/u/865921/blog/196215

你可能感兴趣的文章
摄像机知识
查看>>
小tip:纯CSS让overflow:auto页面滚动条出现时不跳动
查看>>
Linq Like
查看>>
Linux知识积累(4) Linux下chkconfig命令详解
查看>>
centos关机与重启命令
查看>>
[Eth]Mac/Phy/mdio/Rgmii
查看>>
C++中的函数指针和函数对象总结
查看>>
ELK学习总结(3-2)elk的过滤查询
查看>>
快速定位oracle故障-恩墨
查看>>
Redis可视化工具 Redis Desktop Manager
查看>>
Go基础系列:为select设置超时时间
查看>>
Android网络请求之OkHttp框架
查看>>
《Apache Kafka实战》读书笔记-调优Kafka集群
查看>>
小程序开发事项
查看>>
福利 | 2018各大技术大会资料汇总(可下载)
查看>>
寻找下一代CTO - 激发潜能把握成功!!
查看>>
用DELPHI 开发压缩、解压、自解压、加密
查看>>
Linux命令行得到系统IP
查看>>
SQL Server索引的维护 - 索引碎片、填充因子 <第三篇>
查看>>
python类型转换、数值操作(收藏)
查看>>