Servlet分为三种:
- 简单Servlet: 作为以一种程序所必须的开发结构保存下来
- 过滤Servlet:
- 监听Servlet:这两个都是以组建的形式出现的,是额外附加的。
过滤器
之前的Servlet采用继承HttpServlet类的形式完成, 过滤器则使用接口。
如果要用过滤器开发,则首先必须让一个类实现Filter接口
javax.servlet
Interface Filter
根据此包的特点发现,此接口的功能是完成公用协议操作的。
过滤器是以一种组件的形式绑定到WEB应用程序当中的,与其他的WEB应用程序组件不同的是,过滤器采用了链的方式进行处理。
过滤器在开发中使用最频繁的两种操作:
- 编码过滤
- 登录验证
监听器
WEB中的监听主要是对ServletContext, Session, Request进行监听的操作
对Application进行监听
对application监听,实际上就是对ServletContext(Servlet上下文)监听。主要使用
javax.servlet
Interface ServletContextListener :对整个上下文环境的监控
其中
javax.servlet的
Class ServletContextEvent中定义了一个方法:
public ServletContext getServletContext() 取得application对象
javax.servlet
Interface ServletContextAttributeListener:对属性的监听
事件
ServletContextAttributeEvent中有两种方法getName()和getValue()。
监听器就是实现接口覆写方法。
web.xml文件配置中:
- 简单Servlet :<servlet> <servlet-mapping>
- 过滤器: <filter> <filter-mapping>
- 监听器:<listener>
- 先配置过滤器:<filter> <filter-mapping>
- 在配置监听器:<listener>
- 最后配置简单Servlet: <servlet> <servlet-mapping>
对session监听
对session监听有三个接口:在
javax.servlet.http
包中
Method Summary | |
---|---|
void | sessionCreated(HttpSessionEvent se) Receives notification that a session has been created. |
void | sessionDestroyed(HttpSessionEvent se) Receives notification that a session is about to be invalidated. |
- session注销 invalidate()
- 超时时间到了,超时时间30分钟
HttpSessionAttributeListener
对session的属性监听
Method Summary | |
---|---|
void | attributeAdded(HttpSessionBindingEvent event) Receives notification that an attribute has been added to a session. |
void | attributeRemoved(HttpSessionBindingEvent event) Receives notification that an attribute has been removed from a session. |
void | attributeReplaced(HttpSessionBindingEvent event) Receives notification that an attribute has been replaced in a session. |
HttpSessionBindingListener 这个监听可以不用配置直接使用
Method Summary | |
---|---|
void | valueBound(HttpSessionBindingEvent event) Notifies the object that it is being bound to a session and identifies the session. |
void | valueUnbound(HttpSessionBindingEvent event) Notifies the object that it is being unbound from a session and identifies the session. |
对Request监听:
主要使用
ServletRequestListener
对请求监听和ServletRequestAttributeListener 对属性监听 两个接口。这两个接口在javax.servlet.http.*中。但是不常用
监听器实例:在线人员统计
用户在登陆之后,会在在线人员列表中增加此用户名称,这样就可以统计在线用户人数了。
直接在之前的
登陆页面中加入如下代码:
OnlineUserList.java
<pre name="code" class="java">package org.thystar.listenerdemo;
import java.util.Set;
import java.util.TreeSet;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
public class OnlineUserList implements HttpSessionAttributeListener,
HttpSessionListener, ServletContextListener {
private ServletContext app = null; // 用于application属性的操作
public void contextInitialized(ServletContextEvent sce){ //上下文初始化
this.app = sce.getServletContext(); // 取得ServletContext实例
this.app.setAttribute("online",new TreeSet()); //设置空集合
}
public void attributeAdded(HttpSessionBindingEvent event){ //增加session属性
Set<Object> all = (Set)this.app.getAttribute("online"); //取出已有列表
all.add(event.getValue()); // 增加新用户
this.app.setAttribute("online", all); //重新保存
}
public void attributeRemoved(HttpSessionBindingEvent event){
Set all = (Set)this.app.getAttribute("online"); // 取出已有列表
all.remove(event.getValue()); //删除离开用户
this.app.setAttribute("online", all); // 重新保存
}
public void sessionDestroyed(HttpSessionEvent event){
Set all = (Set)this.app.getAttribute("online");
all.remove(event.getSession().getAttribute("userid")); //取出设置的内容
this.app.setAttribute("online", all);
}
public void sessionCreated(HttpSessionEvent event){
}
public void attributeReplaced(HttpSessionBindingEvent event){
}
public void contextDestroyed(ServletContextEvent sce){
}
}
在web.xml中添加代码:
<listener>
<listener-class>org.thystar.listenerdemo.OnlineUserList</listener-class>
</listener>
修改登陆页面login.jsp;
<%@ page contentType = "text/html" pageEncoding="GBK" import = "java.util.*"%>
<html>
<head>
<title>www.thystar.com</title>
<script language = "JavaScript">
function validate(f){
if(!(/^\w{1,15}$/.test(f.userid.value))){
alert("用户ID必须是1~15位");
f.userid.focus();
return false;
}
if(!(/^\w{1,15}$/.test(f.userpass.value))){
alert("密码必须是1~15位");
f.userpass.focus();
return false;
}
return true;
}
</script>
</head>
<body>
<h2>用户登录</h2>
<%
request.setCharacterEncoding("GBK");
%>
<%
List<String> info=(List<String>)request.getAttribute("info");
if(info != null){
Iterator<String> iter = info.iterator();
while(iter.hasNext()){
%>
<h4><%= iter.next() %></h4>
<%
}
}
%>
<form action="LoginServlet" method="post" onSubmit = "validate(this)">
用户ID: <input type = "text" name = "userid"><br>
密 码:<input type = "password" name="userpass"><br>
<input type = "submit" value = "登录">
<input type = "reset" value = "重置">
</form>
<%
String userid = request.getParameter("userid");
if(!(userid == null || "".equals(userid))){
session.setAttribute("userid", userid);
response.sendRedirect("list.jsp");
}
%>
</body>
</html>
最后,给出list.jsp页面:
<%@ page language="java" import="java.util.*" pageEncoding="GBK"%>
<html>
<head>
<title>My JSP 'list.jsp' starting page</title>
</head>
<body>
<h2>在线用户列表</h2>
<%
Set all = (Set)this.getServletContext().getAttribute("online");
Iterator iter = all.iterator();
while(iter.hasNext()){
%>
<h2><%=iter.next() %>,</h2>
<%
}
%>
</body>
</html>
数据库中的信息:
打开登陆页,登陆后再重新打开一个浏览器重复操作,结果如下: