java_web 快速入门之第十八章 过滤器&监听器

一: 过滤器

     过滤器它是 JavaWeb 的三大组件之一。三大组件分别是Servlet 程序、Listener 监听器、Filter 过滤器

    过滤器它是 JavaEE 的规范,也就是一个接口

作用:

    拦截请求过滤响应拦截请求常见的应用场景有权限检查日记操作事务管理等等。

工作原理:

      当客户端发出Web资源的请求时,Web服务器根据应用程序配置文件设置的过滤规则进行检查,若客户请求满足过滤规则,则对客户请求/响应进行拦截,对请求头和请求数据进行检查或改动,并依次通过过滤器链,最后把请求/响应交给请求的Web资源处理。请求信息在过滤器链中可以被修改,也可以根据条件让请求不发往资源处理器,并直接向客户机发回一个响应。当资源处理器完成了对资源的处理后,响应信息将逐级逆向返回。同样在这个过程中,用户可以修改响应信息,从而完成一定的任务。
 

生命周期

  1. 构造器方法init()方法在web工程启动时就会被执行,此时filter过滤器已经被创建。

  2. 每次拦截到请求时,就会执行doFilter()方法。

  3. 在停止web工程时,就会执行destroy()方法,此时会销毁filter过滤器。

可以有多个过滤器,它们运行的先后顺序为:

 ①:web.xml配置文件

        按照先后顺序,从上往下运行

②:注解配置文件

     按照路径首字母的顺序运行

package com.zking.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;
import javax.servlet.annotation.WebFilter;
/**
 * 设置过滤器配置文件
 * @author Administrator
 *
 */
@WebFilter("/LoginFilter")
public class LoginFilter implements Filter {

	/**
	 * 销毁
	 */
	public void destroy() {
		System.out.println("我是过滤器销毁操作,我销毁了");
	}

	/**
	 * 过滤器操作
	 */
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		// 设置编码格式
		request.setCharacterEncoding("utf-8");
		response.setCharacterEncoding("utf-8");
		// 放行
		chain.doFilter(request, response);
		System.out.println("我是过滤器操作,编码格式过滤完毕");

	}

	/**
	 * 初始化
	 */
	public void init(FilterConfig fConfig) throws ServletException {
		System.out.println("我是过滤器初始化操作,我初始化了");
	}

}

 

​
​
package com.zking.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;
import javax.servlet.annotation.WebFilter;

@WebFilter("/LoginFilter")
public class LoginFilter implements Filter {

	/**
	 * 销毁
	 */
	public void destroy() {
		System.out.println("我是过滤器销毁操作,我销毁了");
	}

	/**
	 * 过滤器操作
	 */
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
        Object user = session.getAttribute("user");

        // 如果等于 null,说明还没有登录
        if (user == null) {            servletRequest.getRequestDispatcher("/login.jsp").forward(servletRequest,servletResponse);
            return;
        }else {
            // 让程序继续往下访问用户的目标资源
            filterChain.doFilter(servletRequest,servletResponse);
        }
		System.out.println("我是过滤器操作,编码格式过滤完毕");

	}

	/**
	 * 初始化
	 */
	public void init(FilterConfig fConfig) throws ServletException {
		System.out.println("我是过滤器初始化操作,我初始化了");
	}

}

​

​

二:监听器

       监听器就是一个实现特定接口的普通java程序,这个程序专门用于监听另一个java对象的方法调用或属性改变,当被监听对象发生上述事件后,监听器某个方法将立即被执行

  在java体系中,servlet 监听器有八个接口,而我们常用的有三个:

  1.  HttpServletRequestListener

  2.  HttpSessionListener

  3. ServletContextListener  

监听器的分类:

  1. application 应用级别监听

  2. session 会话级别的监听

  3.  request 请求级别的监听

①.application监听器

1. 实现:ServletContextListener  (常用)

 重写:


  //容器启动时调用
  public void contextInitialized(ServletContextEvent event){
    
  }

  //容器消毁时调用
  public void contextDestroyed(ServletContextEvent event){
    
  }

 ServletContextEvent事件方法:
    getServletContext() ----取得ServletContext对象,即上下文


	event.getServletContext().getContextPath();

②.Session监听器

 实现:HttpSessionListener  (偶尔用)
  重写:

 //session创建时调用
  public void sessionCreated(HttpSessionEvent event){

  }

  //session销毁时调用
  public void sessionDestroyed(HttpSessionEvent event){

  }


  HttpSessionEvent事件方法:
      getSession() -----------取得当前的session

event.getSession().getId();	//得到session的ID


2:实现:HttpSessionAttributeListener (不用,性能差)
  重写:

 //增加属性时触发
  public void attributeAdded(HttpSessionBindingEvent event){
	
  }

  //删除属性时触发
  public void attributeRemoved(HttpSessionBindingEvent event){
	
  }

  //替换属性时触发
  public void attributeReplaced(HttpSessionBindingEvent event){
	
  }

HttpSessionBindingEvent事件方法:

  1. .getSession()  ----------取得session

  2. .getName()  -------------取得属性的名称

  3. .getValue()   ------------取得属性的内容

event.getSession()	//取得session
	event.getName()		//取得属性的名称
	event.getValue()	//取得属性的内容
	


③.request监听器
  实现:ServletRequestListener (不用,性能差)
  重写:

  //请求开始时调用
  public requestInitialized(ServletRequestEvent event){

  }

  //请求结束时调用
  public requestDestroyed(ServletRequestEvent event){

  }

ServletRequestEvent事件方法:

  1. .getServletRequest()-------取得ServletRequest对象

  2.  .getServletContext()-------取得ServletContext对象

event.getServletRequest().getRemoteAddr();	//得到IP地址
	event.getServletContext().getContextPath();	//得到当前路径

注意:

          为什么说session监听器和request监听器一般都不用?

答:以request监听器为例,如果采用request监听,那就意味着每次请求都要触发一次监听,这大大降低了程率的效率,因此很少用

案例:监听在线人数   


          分析:创建一个会话就+1,销毁了会话则-1(在会话被创建时,往全局变量中+1;会话被关闭时,全局变量-1)
      服务器停止则移除 count
 


public class AppListrener implements ServletContextListener,HttpSessionListener {
	
	ServletContext app=null;
	
	//容器销毁时调用
	public void contextDestroyed(ServletContextEvent sce) {
		// TODO Auto-generated method stub
		System.out.println("容器销毁了");
		
	}
	//容器初始化时调用
	public void contextInitialized(ServletContextEvent sce) {
		// TODO Auto-generated method stub
		System.out.println("容器初始化了");
		app=sce.getServletContext();
		Integer count=0;
		app.setAttribute("cut", count);
		System.out.println(count+"___");
	}
	
	//session创建时调用
	public void sessionCreated(HttpSessionEvent arg0) {
		// TODO Auto-generated method stub
		System.out.println("session创建时调用");
		Integer count=(Integer)app.getAttribute("cut");
		
		if(count==null){
			count=0;
		}
		count++;
		System.out.println("创建时:"+count);
		app.setAttribute("cut", count);
	}
	
	//session销毁时调用
	public void sessionDestroyed(HttpSessionEvent arg0) {
		// TODO Auto-generated method stub
		System.out.println("session销毁时调用");
		Integer count=(Integer)app.getAttribute("cut");
		
		if(count==null){
			count=0;
		}
		count--;
		System.out.println("注销时:"+count);
		app.setAttribute("cut", count);
	}



web.xml文件的配置

 <listener>
  	<listener-class>com.servlet.AppListrener</listener-class>
  </listener>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值