Servlet过滤器与事件处理
1.编写、部署、测试一个ServletContext事件监听器。
【步骤1】编写监听器类MyServletContextListener.java,Web应用程序启动时创建一个数据源对象,并将其保存在ServletContext作用域中,Web应用销毁时将其清除;在ServletContext对象上添加属性、删除属性和替换属性时,在Tomcat日志中记录有关信息,包括提示信息、属性名和属性值等。
【步骤2】通过注释或在web.xml文件中注册该监听器类。
【步骤3】编写监听器测试页面:contextListenerTest.jsp:使用监听器创建的数据源对象连接是一次实验创建的MySQL数据库test,以表格的形式显示其中books数据表的所有内容。
【步骤4】在Tomcat下发布该Web应用,启动Tomcat,访问测试页面。
【步骤5】检查日志文件
打开<CATALINA_HOME>\logs目录中的localhost.yyyy-mm-dd.log日志文件,查看执行事件监听器后写到日志文件中的信息。
1.MyServletContextListener.java
import java.util.Date;
import javax.servlet.*;
public final class MyServletContextListener implements ServletContextListener, ServletContextAttributeListener {
private ServletContext context = null;
public void contextInitialized(ServletContextEvent sce){
context = sce.getServletContext();
context.log("应用程序已启动:"+new Date());
}
public void contextDestroyed(ServletContextEvent sce){
context = sce.getServletContext();
context.log("应用程序已关闭:"+new Date());
}
public void attributeAdded(ServletContextAttributeEvent sce){
context = sce.getServletContext();
context.log("添加一个属性:"+sce.getName()+":"+sce.getValue());
}
public void attributeRemoved(ServletContextAttributeEvent sce){
context = sce.getServletContext();
context.log("删除一个属性:"+sce.getName()+":"+sce.getValue());
}
public void attributeReplaced(ServletContextAttributeEvent sce){
context = sce.getServletContext();
context.log("替换一个属性:"+sce.getName()+":"+sce.getValue());
}
}
2.web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>homework6</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<listener>
<listener-class>MyServletContextListener</listener-class>
</listener>
<listener>
<listener-class>MySessionListener</listener-class>
</listener>
<listener>
<listener-class>MyRequestListener</listener-class>
</listener>
<filter>
<filter-name>AuditFilter</filter-name>
<filter-class>com.filter. AuditFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>AuditFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
3.contextListenerTest.jsp
<%@ page import="java.io.IOException" %>
<%@ page import="java.io.PrintWriter" %>
<%@ page import="java.util.Date" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%
ServletContext context =null;
context = getServletConfig().getServletContext();
response.setContentType("text/html");
out.println("<html><head><title>Event Test</title></head>");
Integer anInteger =new Integer(100);
Date aDate = new Date();
context.setAttribute("obj",anInteger); //添加属性
context.setAttribute("obj",aDate); //替换属性
context.removeAttribute("obj"); //删除属性
out.println("<h3 align=center>"+ "已在ServletContext对象上添加、替换和删除了属性</h3>");
out.println("</body></html>");
out.close();
%>
</body>
</html>
2.编写一个HttpSession事件监听器用来记录当前在线人数。
【步骤1】编写MySessionListener监听器处理类,监视Web应用会话创建事件:每创建一个新的会话对象,就将其保存到会话对象的列表数组中,并将用户会话对象列表保存在ServletContext作用域中的sessionList属性中,同时向日志中写入“创建一个新会话”以及该会话的ID。当一个会话对象被删除时,从用户会话对象列表中删除该会话对象并保存,同时向日志中写入“删除一个会话”以及该会话的ID。
【步骤2】在web.xml文件中注册该事件监听器。
【步骤3】编写一个测试该监听器的页面sessionDisplay.jsp,显示当前应用所有在线的会话对象的id及创建时间。多打开几个浏览器窗口,模拟多用户访问,查看多用户会话统计出的结果。
<%@ page contentType=“text/html;charset=gb2312” %>
<%@ page import="java.util.* " %>
<%@ taglib prefix=“c” uri=“http://java.sun.com/jsp/jstl/core” %>
1.MySessionListener监听器处理类
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
public final class MySessionListener implements HttpSessionListener{
private int count = 0;
public void sessionCreated(HttpSessionEvent se){
count++;
se.getSession().getServletContext().setAttribute(
"onlineCount",new Integer(count));
}
public void sessionDestroyed(HttpSessionEvent se){
count--;
se.getSession().getServletContext().setAttribute(
"onlineCount",new Integer(count));
}
}
2.web.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>homework6</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<listener>
<listener-class>MyServletContextListener</listener-class>
</listener>
<listener>
<listener-class>MySessionListener</listener-class>
</listener>
<listener>
<listener-class>MyRequestListener</listener-class>
</listener>
<filter>
<filter-name>AuditFilter</filter-name>
<filter-class>com.filter. AuditFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>AuditFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
3.sessionDisplay.jsp
<%@ page contentType="text/html;charset=gb2312" %>
<%@ page import="java.util.* " %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<body>
<table border="1">
<c:forEach var="sess" items="${applicationScope.sessionList}">
<tr><td><c:out value="${sess.id}" /></td>
<td><c:out value="${sess.creationTime}"/></td>
</tr>
</c:forEach>
</table>
</body>
</html>
3. 编写一个ServletRequestListener监听器,记录某个页面自应用程序启动以来被访问的次数。
【步骤1】编写监听器接口MyRequestListener,在对指定页面onlineCount.jsp发送请求时进行该页面访问次数计数器累加,并将计数器变量保存到应用作用域的属性中。
【步骤2】在web.xml文件中注册该监听器。
【步骤3】编写一个JSP页面onlineCount.jsp。
<%@ page contentType=“text/html;charset=gb2312” %>
自应用程序启动以来,该页面被访问了 <%=application.getAttribute("count")%> 次
1.MyRequestListener
import javax.servlet.http.HttpServletRequest;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
public final class MyRequestListener implements ServletRequestListener{
private int count = 0;
public void requestInitialized(ServletRequestEvent re){
HttpServletRequest request= (HttpServletRequest)re.getServletRequest();
if(request.getRequestURI().equals("/helloapp/onlineCount.jsp")){
count++;
re.getServletContext().setAttribute("count",new Integer(count));
}
}
public void requestDestroyed(ServletRequestEvent re){
}
}
2.onlineCount.jsp
<%@ page contentType="text/html;charset=gb2312" %>
<html>
<head><title>Listener test</title>
</head>
<body>
欢迎您,您的IP地址是<%= request.getRemoteAddr() %>
<p>自应用程序启动以来,该页面被访问了
<font color="blue" ><%=application.getAttribute("count")%>
</font>次<br>
</body>
</html>
3.web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>homework6</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<listener>
<listener-class>MyServletContextListener</listener-class>
</listener>
<listener>
<listener-class>MySessionListener</listener-class>
</listener>
<listener>
<listener-class>MyRequestListener</listener-class>
</listener>
<filter>
<filter-name>AuditFilter</filter-name>
<filter-class>com.filter. AuditFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>AuditFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
4.编写一个过滤器AuditFilter.java,审计用户对资源的访问。
【步骤1】编写过滤器AuditFilter.java,实现当用户访问应用程序任何资源时,将用户的IP地址和主机名写入日志文件中。
【步骤2】通过注释配置过滤器。过滤器映射使用的URL模式为/*,这表示将该过滤器映射到Web应用程序的任何资源。如果只对某些资源(如JSP页面审计,则可以指定具体的资源)。
【步骤3】访问该应用程序中的任何一个资源,如使用下面的URL访问onlineCount.jsp:
http://localhost:8080/ch10/onlineCount.jsp
然后打开<CATALINA_HOME>\logs目录中的localhost.2012-05-15.log文件中有下面一行(访问多个资源就会有多行):
信息: RemoteAddress:127.0.0.1, RemoteHost:127.0.0.1
1.AuditFilter.java
import java.io.IOException;
import javax.servlet.*;
import javax.servlet.http.*;
public class AuditFilter implements Filter {
protected FilterConfig config;
public void init(FilterConfig filterConfig) throws ServletException {
this.config = filterConfig;
}
public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain)
throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest)request;
HttpServletResponse res = (HttpServletResponse)response;
String addr = req.getRemoteAddr();
String user = req.getRemoteHost();
config.getServletContext().log("RemoteAddress:"+addr+ ",RemoteHost:"+user);
chain.doFilter(req, res);
}
public void destroy() {
}
}
2.onlineCount.jsp
<%@ page contentType="text/html;charset=gb2312" %>
<html>
<head><title>Listener test</title>
</head>
<body>
欢迎您,您的IP地址是<%= request.getRemoteAddr() %>
<p>自应用程序启动以来,该页面被访问了
<font color="blue" ><%=application.getAttribute("count")%>
</font>次<br>
</body>
</html>