过滤器filter与监听器listener

1、过滤器filter

1 概念filter

***filter:过滤器
***作用:对一个或者一类请求进行拦截 根据条件选择放行
web三大组件:servlet+filter+listener
    servlet(秘书):接受请求 处理数据 给与响应
    filter(保安):对请求进行拦截 选择放行
    listener(FBI):对域对象的增删改查进行监控           

2 filter使用

创建filter

package filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class DemoFilter implements Filter {
	{
		System.out.println("DemoFilter:::构造代码块!!!");
	}

	@Override
	public void destroy() {
		System.out.println("DemoFilter:::destroy!!!");
	}

	@Override
	public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)
			throws IOException, ServletException {

		System.out.println("DemoFilter::::doFilter" + 1);
		// 调用FilterChain的dofilter方法 放行请求
		arg2.doFilter(arg0, arg1);
		System.out.println("DemoFilter::::doFilter" + 2);

	}

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		System.out.println("DemoFilter:::init!!!");
	}

}

在web.xml配置filter

注意:xml用来设置拦截路径:/*:从项目路径开始

  <filter>
    <filter-name>DemoFilter</filter-name>
    <filter-class>filter.DemoFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>DemoFilter</filter-name>
    <url-pattern>/DemoServlet</url-pattern>
    <url-pattern>/s/*</url-pattern>
    <url-pattern>*.do</url-pattern>
    <url-pattern>/s</url-pattern>
  </filter-mapping>

创建servlet

package servlet;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class DemoServlet extends HttpServlet {

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setContentType("text/html;charset=utf-8");
		System.out.println("servlet::::DemoServlet");
		response.getWriter().print("<font color='red'>DemoServlet:::success</font>");
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}

3 filter作用

* 访问权限控制

* 对request和response对象的功能进行控制

* 在请求处理之前执行预处理工作 在请求处理之后执行响应内容的加工:

  (提取请求处理的公共代码)

编码集过滤器

@Override
public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)
    throws IOException, ServletException {

    //提取公共代码:对request和response设置编码集
    arg0.setCharacterEncoding("UTF-8");
    arg1.setCharacterEncoding("utf-8");
    arg1.setContentType("text/html;charset=utf-8");
    arg2.doFilter(arg0, arg1);

}

4 注意事项

* filter是单例 一个类只有一个对象
* filter单例对象 是tomcat启动时创建的
* filter可以拦截所有请求:包括对servlet、jsp、css、js、html、img
* Filter的doFilter方法用于拦截和url匹配的请求

* FilterChain的doFilter方法用于拦截的放行:::两个doFilter方法的参数列表不同

5 Filter的生命周期

  • 创建对象
 tomcat启动时 会创建filter的单例对象
  • 初始化
filter对象一旦创建 tomcat就会调用filter对象的init方法 对filter对象进行初始化
  • 拦截请求
每次filer配置的url被请求一次,tomcat就会调用filter对象的doFilter方法来拦截请求
然后通过FilterChain的doFiler来选择放行请求
  • 销毁对象
tomcat在关闭之前 会调用filer对象的destroy方法 来销毁对象 释放内存

2、监听器listener

1 listener概念

***listener:监听器
	监听域对象的某一事件 当此事件发生时 就执行对应的代码
listener:web的三大组件
	注意:只能监听域对象+监听器中的代码是被动执行的
  • 分类
域属性监听器:监听request/session/servletContext的属性的增删改:cud 
	HttpSessionAttributeListener,ServletRequestAttributeListener,ServletContextAttributeListener	
域对象的生死监听器:监听request/session/servletContext对象创建和销毁

2 域属性监听器

package filter;

import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;

public class DemoAttributelListener implements HttpSessionAttributeListener {

	@Override
	public void attributeAdded(HttpSessionBindingEvent se) {
		// 统计人数:需要被整个项目共享 装在servletcontext域中:::要求会员登录 在seesion域中添加属性user
		if (se.getName().equals("user")) { // 会员+1
			// 获取servletcontext域中的count属性
			Object count = se.getSession().getServletContext().getAttribute("count");
			// 你是第一个登录者
			if (count == null) {
				se.getSession().getServletContext().setAttribute("count", 1);
			} else { 
				// 原来的值+1
				se.getSession().getServletContext().setAttribute("count", ((Integer) count) + 1);
			}
		}
	}

	@Override
	public void attributeRemoved(HttpSessionBindingEvent se) {
		// 统计人数:需要被整个项目共享 装在servletcontext域中:::要求会员登出:删除session中的域属性user
		if (se.getName().equals("user")) { // 会员+1
			// 获取servletcontext域中的count属性
			Object count = se.getSession().getServletContext().getAttribute("count");
			// 原来的值-1
			se.getSession().getServletContext().setAttribute("count", ((Integer) count) - 1);
		}
	}

	@Override
	public void attributeReplaced(HttpSessionBindingEvent se) {
	
		System.out.println(se.getSession().getId()+se.getName());
		System.out.println( se.getName() + se.getValue() + se.getSession().getAttribute(se.getName()));
	}

}
  • 配置监听器
<!-- 配置监听器 -->
<listener>
    <listener-class>/filter/DemoAttributelListener</listener-class>
</listener>

3 域对象生死监听器

package filter;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

public class DemoAttributelListener implements ServletRequestListener, HttpSessionListener, ServletContextListener {
	public void requestDestroyed(ServletRequestEvent sre) {
	}

	// 统计每个页面的访问次数
	public void requestInitialized(ServletRequestEvent sre) {
		// 每个页面对应一个 访问次数 数据存储在map中
		// 此数据被项目的所有资源共享:数据应该存储在servletcontext域中
		HttpServletRequest req = (HttpServletRequest) sre.getServletRequest();
		System.out.println("requestInitialized:::请求的资源路径:::" + req.getServletPath());
		String path = req.getServletPath();
		// 获取servletContext域中添加属性:countMap
		Map<String, Integer> countMap = (Map<String, Integer>) sre.getServletContext().getAttribute("countMap");
		countMap.put(path, countMap.containsKey(path) ? (countMap.get(path) + 1) : 1);

	}

	public void sessionCreated(HttpSessionEvent se) {
	}

	public void sessionDestroyed(HttpSessionEvent se) {
	}

	public void contextDestroyed(ServletContextEvent sce) {
	}

	public void contextInitialized(ServletContextEvent sce) {
		System.out.println("contextInitialized");
		// 项目初始化就在servletContext域中添加属性:countMap
		Map<String, Integer> countMap = new HashMap<>();
		sce.getServletContext().setAttribute("countMap", countMap);
	}
}

4 实现练习

  • 统计:会员在线人数:::session的属性监听器
  • 统计:在线人数:::session生死监听器
  • 统计:资源访问量:::request的生死监听器
posted @ 2021-10-16 16:43  RenVei  阅读(40)  评论(0编辑  收藏  举报