前言:在web应用中,有时候你想在web应用程序启动或关闭的时候执行一些任务,或者你想见他Session的创建和关闭等你就可以通过监听器来实现。那么Servlet来8个监视器接口,下面一一讲解一下。

1:ServletContextListener和ServletContextAttributeListener

1.1:ServletContextListener主要用于容器的启动和关闭时候进行监听。有2个方法分别用于监听容器启动和关闭。比喻我们在容器启动的时候做数据库连接的初始化。容器关闭时候可以通知从来启动另一个容器保证应用程序的稳定运行

代码如下

public class MyServletContextListener implements ServletContextListener{

    public void contextInitialized(ServletContextEvent sce) {
System.out.println("Servlet上下文对象开始进行初始化");
} public void contextDestroyed(ServletContextEvent sce) {
System.out.println("Servlet上下文对象开始销毁");
}
}

web.xml配置(下同)

 <listener>
<listener-class>com.lp.listensrs.MyServletContextListener</listener-class>
</listener>

1.2:ServletContextAttributeListener主要用来监听上下文对象属性变化的主要有3个方法分别来监听添加属性,删除属性,以及属性值得替代。

public class MyServletContextAttributeListener implements ServletContextAttributeListener{

    public void attributeAdded(ServletContextAttributeEvent scab) {
System.out.println("添加的ServletContext属性是"+scab.getName());
} public void attributeRemoved(ServletContextAttributeEvent scab) {
System.out.println("删除的ServletContext属性是"+scab.getName());
} public void attributeReplaced(ServletContextAttributeEvent scab) {
System.out.println("属性值进行替代");
}
}

然后我们在jsp文件上加上

       application.setAttribute("sqlName", "admin");
application.setAttribute("sqlName", "replaceadmin");
application.removeAttribute("sqlName");

运行可以看到结果为

2:ServletRequestListener和ServletRequestAttributeListener

2.1:ServletRequestListener主要用来监听httpRequest对象请求和响应的。通过这个监听器可以监听应用程序中每个HTTP请求的数量。代码如下

public class MyServletRequestListener implements ServletRequestListener{
public void requestDestroyed(ServletRequestEvent sre) {
System.out.println("对请求进行响应");
} public void requestInitialized(ServletRequestEvent sre) {
HttpServletRequest request=(HttpServletRequest)sre.getServletRequest();
String url=request.getRequestURL().toString();
System.out.println("收到Request请求"+url);
}
}

然后我们可以看结果

2.1:ServletRequestAttributeListener这个是监听Request属性的变化和ServletContent基本一样。代码如下

public class MyServletRequestAttributeListener implements ServletRequestAttributeListener
{ public void attributeAdded(ServletRequestAttributeEvent srae) {
System.out.println("添加的属性:"+srae.getName());
} public void attributeRemoved(ServletRequestAttributeEvent srae) {
System.out.println("删除的属性:"+srae.getName());
} public void attributeReplaced(ServletRequestAttributeEvent srae) {
String str =MessageFormat.format(
"ServletRequest域对象中替换了属性:{0}的值"
,srae.getName());
System.out.println(str);
}
}

3:HttpSessionListener、HttpSessionAttributeListener、HttpSessionBindingListener

3.1:HttpSessionListener主要目的是监听Session的创建和消耗的。这里只写一个简单的例子

public class MyHttpSessionListener implements HttpSessionListener{
public void sessionCreated(HttpSessionEvent se) {
System.out.println("Session创建,Session的Id为"+se.getSession().getId()); } public void sessionDestroyed(HttpSessionEvent se) {
System.out.println("Session销毁"); }
}

3.2:HttpSessionAttributeListener、HttpSessionBindingListener这两个我重点说下,前者主要是监听整个应用程序Session属性的变化,而后者主要是自身属性来实现的,以便属性知道他何时添加到一个Session中,或者这个属性从Session删除,(HttpSessionBindingListener并不需要在xml中进行配置)现在来演示这个HttpSessionBindingListener。

我们现在做个简单的在线人数统计。

首先做个userList来存储上线的人数,采用单例模式,同时使用vector来避免线程安全问题。代码如下

public class UserList {

    private static final UserList userList=new UserList();
private Vector<String> vector;
public UserList()
{
vector=new Vector<String>();
}
public static UserList getInstance(){
return userList;
}
public void addUser(String name){
if(name!=null&&name!=""){
vector.addElement(name);
}
}
public void removeUser(String name){
if (name!=null&name!="") {
vector.remove(name);
}
}
public Enumeration<String> getUserList(){
return vector.elements();
}
public int getUserCount(){
return vector.size();
}
}

然后在定义一个UserBean来实现HttpSessionBindingListener从而达到当UserBean对象加入Session时调用valueBound方法删除UserBean对象时候调用valueUnbound方法。

public class UserBean implements HttpSessionBindingListener{

    private String userName;
private UserList ul=UserList.getInstance();
public UserBean(){};
public UserBean(String name){
this.userName=name;
}
public void valueBound(HttpSessionBindingEvent event) {
ul.addUser(userName);
System.out.println("被调用");
} public void valueUnbound(HttpSessionBindingEvent event) {
ul.removeUser(userName);
System.out.println("移除被调用");
} public String getUserName() {
return userName;
} public void setUserName(String userName) {
this.userName = userName;
} }

然后我们在来定义一个Servlet来用户登录并且把UserBean对象加入Session中如下

public class OnlineUserServlet extends HttpServlet {
private static final long serialVersionUID = 1L; public OnlineUserServlet() {
super();
} protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
String userName=request.getParameter("userName");
String pwd=request.getParameter("password");
if (userName==null||userName==""||pwd==null||pwd=="") {
response.sendRedirect("login.html");
return;
}
HttpSession session=request.getSession();
UserBean userBean=(UserBean)session.getAttribute("user");
UserList ul=UserList.getInstance();
if (userBean==null||!userName.equals(userBean.getUserName())) {
userBean=new UserBean(userName);
session.setAttribute("user", userBean);
}
response.setContentType("text/html;charset=gb2312");
PrintWriter out=response.getWriter();
out.println("欢迎用户<b>"+userName+"</b>登录"); out.println("<br>当前在线用户列表</br>");
Enumeration<String> enums=ul.getUserList();
int i=0;
while (enums.hasMoreElements()) {
out.println(enums.nextElement());
out.println("&nbsp;&nbsp;&nbsp;");
if(i++==10){
out.println("<br>");
}
}
out.println("<br>当前在线人数:"+i);
out.println("<p><a href='logout'>退出登录</>");
out.close(); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}

然后在写一个Servlet退出,把UserBean从Session中删除

public class LogOutServlet extends HttpServlet{
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=gb2312");
HttpSession session=request.getSession();
UserBean userBean=(UserBean)session.getAttribute("user");
session.removeAttribute("user");
PrintWriter out=response.getWriter();
out.println("<html><head><title>退出登录</title></head><body>");
out.println(userBean.getUserName()+"你已经退出登录");
out.println("<a href='index.html'>重新登录</a>");
out.println("</body></html>");
out.close();
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}

最后写一个index.html登录页面

<form action="online" method="post">
<table>
<tr>
<td>用户名:<input type="text" name="userName" /></td>
<td>密码:<input type="password" name="password" /></td>
<td><input type="submit" value="提交" /></td>
</tr>
</table>
</form>

先用火狐浏览器登录结婚

然后我在用谷歌浏览器登录

javaweb回顾第十二篇监听器的更多相关文章

  1. javaWeb核心技术第十二篇之分页和条件

    分页:limit ?,? 参数1 : startIndex 开始索引. 参数2 : pageSize 每页显示的个数 n 表示第几页 给定一个特殊的单词 pageNumber select * fro ...

  2. 第十二篇 Integration Services:高级日志记录

    本篇文章是Integration Services系列的第十二篇,详细内容请参考原文. 简介在前一篇文章我们配置了SSIS内置日志记录,演示了简单和高级日志配置,保存并查看日志配置,生成自定义日志消息 ...

  3. 【译】第十二篇 Integration Services:高级日志记录

    本篇文章是Integration Services系列的第十二篇,详细内容请参考原文. 简介在前一篇文章我们配置了SSIS内置日志记录,演示了简单和高级日志配置,保存并查看日志配置,生成自定义日志消息 ...

  4. 解剖SQLSERVER 第十二篇 OrcaMDF 行压缩支持(译)

    解剖SQLSERVER 第十二篇   OrcaMDF 行压缩支持(译) http://improve.dk/orcamdf-row-compression-support/ 在这两个月的断断续续的开发 ...

  5. 第十二篇 SQL Server代理多服务器管理

    本篇文章是SQL Server代理系列的第十二篇,详细内容请参考原文 在这一系列的上一篇,我们查看了维护计划,一个维护计划可能会创建多个作业,多个计划.你还简单地看了SSIS子系统,并查看了维护计划作 ...

  6. Python之路【第十二篇】:JavaScrpt -暂无内容-待更新

    Python之路[第十二篇]:JavaScrpt -暂无内容-待更新

  7. Python开发【第二十二篇】:Web框架之Django【进阶】

    Python开发[第二十二篇]:Web框架之Django[进阶]   猛击这里:http://www.cnblogs.com/wupeiqi/articles/5246483.html 博客园 首页 ...

  8. 【译】第十二篇 SQL Server代理多服务器管理

    本篇文章是SQL Server代理系列的第十二篇,详细内容请参考原文 在这一系列的上一篇,我们查看了维护计划,一个维护计划可能会创建多个作业,多个计划.你还简单地看了SSIS子系统,并查看了维护计划作 ...

  9. 跟我学SpringCloud | 第十二篇:Spring Cloud Gateway初探

    SpringCloud系列教程 | 第十二篇:Spring Cloud Gateway初探 Springboot: 2.1.6.RELEASE SpringCloud: Greenwich.SR1 如 ...

随机推荐

  1. Windows Phone 8.1 新特性 - 页面导航

    本篇介绍一下Windows Phone 8.1 中页面导航的实现方式. 大家对Windows Phone 8 中页面导航的实现一定不陌生,我们使用 NavigationService 来实现.具体写法 ...

  2. appframework build目录各文件之包含内容

    { "build/css/af.ui.css": [ "css/main.css", "css/appframework.css", &qu ...

  3. case when then else end 用法

    前段时间做项目过程中制作报表时编写的sql需要用到的case when then else end,因此将case的用法总结一下吧. CASE命令有两种语句格式:语法形式1:CASE expressi ...

  4. 编译系统中的LR与LL理解

    编译原理:LL(1),LR(0),SLR(1),LALR(1),LR(1)对比 LL(1)定义:一个文法G是LL(1)的,当且仅当对于G的每一个非终结符A的任何两个不同产生式 A→α|β,下面的条件成 ...

  5. HDU4430 Yukari's Birthday(枚举+二分)

    Yukari's Birthday  HDU4430 就是枚举+二分: 注意处理怎样判断溢出...(因为题目只要10^12) 先前还以为要用到快速幂和等比数列的快速求和(但肯定会超__int64) 而 ...

  6. WebStorm 11激活方法

    由于最新jetbrains发布了IntelliJ IDEA 15. PyCharm 5.PhpStorm10.WebStorm 11等各个版本,但是改变了注册方法.原先的注册码包括注册机都已经不能使用 ...

  7. 建立自己的Visual Studio工程模板

    如果你需要经常创建自己的特殊工程的话,那么预先建立自定义的工程模块,可能会让你的工作变得更轻松一些. 实现方法很简单,一共只需要六个步骤: 一. 新建工程 * 这里选用空白的Web工程. 二. 建立必 ...

  8. 【Win10 UWP】URI Scheme(二):自定义协议的处理和适用场景

    上一篇提到Windows Store协议的使用,其实Windows Store协议仅是系统内建的一种协议规则.我们也可以自己定义一套规范的URI-Scheme,除了可以给其他App调用外,本应用也可以 ...

  9. 如何把.cs文件编译成DLL文件

    开始--程序--Microsoft Visual Studio.NET 2013--Visual Studio.NET工具,点击其中的"VS2013 开发人员命令提示",就会进入M ...

  10. ORACLE EXP/IMP的使用详解

    导入/导出是ORACLE幸存的最古老的两个命令行工具,其实我从来不认为Exp/Imp 是一种好的备份方式,正确的说法是Exp/Imp只能是一个好的转储工具,特别是在小型数据库的转储,表空间的迁移,表的 ...