过滤器和监听器

过滤器和监听器

**web三大组件:**servlet、过滤器和监听器。

过滤器 -->1.我们每次在servlet的实现类中 每次都要进行设置字符编码 文本格式;

         2.图片 pc端 手机端 下载下来的时候 图片大小不一致 --);

	  3.在新闻管理项目中,你的分类基本是不变的,用application作用域进行存储 但是什么时候存呢  (首页一打开就存?)  万一别人进的是添加页面

	  4.你在浏览网页 提示让你登录以后才能进行别的操作 

1. 掌握过滤器的使用

1.1 理解过滤器的特点和执行原理

每次在请求前都要进行一系列的编码问题解决和响应格式问题解决。

每次请求前需要记录请求日志,响应后也需要记录响应日志。

检查当前用户是否有处理目标资源的权限。(查看用户是否登录)

过滤器就可以实现上述的处理。

过滤器用于拦截传入的请求和传出的响应,监视、修改或以某种方式处理正在客户端和服务器之间交换的数据流。

过滤器会过滤两次,一次请求过滤,一次响应过滤。

在目标资源执行请求处理前进行过滤,在目标资源处理后响应前进行过滤。
在这里插入图片描述
在这里插入图片描述
目标资源如 jsp页面/servlet等

web容器就是 tomcat

1.2 掌握过滤器的创建和配置

接口是一种能力

ctrl+shift+t全局搜索类

ctrl+t查看继承体系

ctrl+o查看方法

filter过滤

**Filter接口:**类似于Servlet接口 用于执行过滤操作的接口 javax.servlet

在这里插入图片描述

**FilterConfig接口:**类似于ServletConfig接口 用于获取Filter配置参数信息的接口
在这里插入图片描述

  • 创建一个类实现过滤器接口

    public class HelloFilter1 implements Filter {
    
    	@Override
    	public void destroy() {}
    
    	// 执行过滤
    	@Override
    	public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
    			throws IOException, ServletException {
    		System.out.println("----->正在执行请求过滤------>");
    		filterChain.doFilter(request, response); // 放行
    		System.out.println("----->正在执行响应过滤------>");
    	}
    
    	@Override
    	public void init(FilterConfig filterConfig) throws ServletException {}
    
    }
    
  • 在web.xml中配置此过滤器

      <!-- 配置过滤器 -->
      <filter>
      	<filter-name>helloFilter1</filter-name>
      	<filter-class>cn.kgc.demo1.HelloFilter1</filter-class>
      </filter>
      
      <filter-mapping>
      	<filter-name>helloFilter1</filter-name>
      	<!-- http://localhost:8080/newsmgr/xx/xxx?opr=xxx -->
      	<!-- 过滤器能够给哪些请求进行过滤  (过滤规则) -->
      	<!-- 此规则同样适用于servlet -->
      	<!-- 
      		完全匹配:
      			例如:/hello  它只能匹配到 http://localhost:8080/newsmgr/hello
      		目录匹配:
      			例如:/hello/* 
      				它能匹配到:http://localhost:8080/newsmgr/hello/test1
      				它能匹配到:http://localhost:8080/newsmgr/hello/test2/xxx
      		扩展名匹配:
      			例如:
      				*.do
      				*.action
      				*.html
      				它能匹配到:http://localhost:8080/newsmgr/xxx/xxx/xx.do
      	 -->
    //  /hello/*  如果没有前面的/  就是包含hello就可以   加上表示目录     
      	<url-pattern>/hello/*</url-pattern>
      </filter-mapping>
    

在这里插入图片描述
你也可以这样创建filter 会自动帮你配置好在web.xml里面的内容
在这里插入图片描述
还可以通过注解配置过滤器。

@WebFilter(filterName="helloFilter2",urlPatterns= {"/hello/*"})
public class HelloFilter2 implements Filter {
    
}
1.3 Filter的生命周期【面试题】

回顾Servlet的生命周期:

当第一次请求过来的时候,服务器会对对应的Servlet进行实例化(构造方法)和初始化(init()方法)。

每一次请求过来的时候,服务器都会执行service方法然后根据请求方式的不同,执行doXx()方法。

当服务器被正常关闭的时候会调用Servlet的destroy方法

Filter的生命周期:

当服务器启动时,过滤器就会进行实例化(构造方法)和初始化(init方法)!

当请求符合过滤器过滤规则时,会执行doFilter方法,如果过滤合格,可以选择放行到下一个过滤器(过滤器链),同理响应时也会再次进行响应过滤。

当服务器正常关闭时,会调用destroy方法进行销毁。

在这里插入图片描述

1.4 理解过滤器链

当多个过滤器的匹配规则都处于交集状态,那么会形成过滤器链,执行完对应的过滤器之后,会依次执行后续的,最后才执行目标资源。(它的顺序由web.xml中的filter-mapping标签决定)

在这里插入图片描述

1.5 初始化参数设置

类似于Servlet的初始化参数配置。

@WebFilter(filterName = "characterEncodingFilter", urlPatterns = { "/*" }, initParams = {
		@WebInitParam(name = "encoding", value = "utf-8") })
public class CharacterEncodingFilter implements Filter {
	private String defaultEncoding = "utf-8";

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		String encoding = filterConfig.getInitParameter("encoding");
		if (encoding != null) {
			defaultEncoding = encoding;
		}
	}

	// 解决中文编码问题
	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		request.setCharacterEncoding(defaultEncoding);
		// 我们在请求中就要用到out对象 所以在请求前开始在执行
		response.setContentType("text/html;charset="+defaultEncoding );
		response.setCharacterEncoding(defaultEncoding);
		chain.doFilter(request, response);
	}

	@Override
	public void destroy() {

	}

}

2. 掌握监听器的使用

你也可以右键去搜索listener 实现一下你要实现的接口,这样创建的时候,以后就不需要在web.xml中进行配置了
在这里插入图片描述

2.1 理解监听器的作用

**监听器:**用于监听我们一些特别的作用域对象的活动的一种组件。

ServletContext(application作用域)、HttpSession(session作用域)、ServletRequest(request作用域)三个域对象

在这里插入图片描述

2.2 了解监听器的分类
  • 监听作用域创建和销毁的监听器
    • ServletContextListener
    • HttpSessionListener
    • ServletRequestListener
  • 监听作用域属性列表变化的监听器
    (只要有属性在添加移除 我就触发 但是我希望有用户对象的属性再添加的我才触发 需要借助下面的感知性监听器)
    • ServletContextAttributeListener
    • HttpSessionAttributeListener
    • ServletRequestAttributeListener
  • 感知型监听器
    • HttpSessionBindingListener
    • HttpSessionActivationListener
2.3 掌握监听器的定义和配置

监听作用域创建和销毁的监听器

  • 创建一个监听器实现对应的监听器接口,服务器启动的时候执行初始化,服务器关闭时执行销毁操作。

    public class MyListener1 implements ServletContextListener {
    
    	// 监听销毁
    	@Override
    	public void contextDestroyed(ServletContextEvent arg0) {
    		System.out.println("正在执行销毁");
    	}
    
    	// 监听初始化
    	@Override
    	public void contextInitialized(ServletContextEvent arg0) {
    		System.out.println("正在执行初始化");
    	}
    
    }
    
  • 在web.xml中配置对应的监听器全类名

    <listener>
    	<listener-class>cn.kgc.demo1.MyListener1</listener-class>
    </listener>
    

监听作用域属性列表变化的监听器

  • 创建一个监听器实现对应的监听器接口
HttpSession session = request.getSession();
	User user=new User("heise","123");
	属性添加session.setAttribute("loginUser",user);
   属性移除session.removeAttribute()
   属性修改session.setAttribute("userName", "heiUpdate");
public class MyListener2 implements HttpSessionAttributeListener {

	// 属性添加
	@Override
	public void attributeAdded(HttpSessionBindingEvent sessionBindingEvent) {
		String name = sessionBindingEvent.getName();
		Object value = sessionBindingEvent.getValue();
		System.out.println("有属性在添加!"+name+"-->"+value);
	}

	// 属性移除
	@Override
	public void attributeRemoved(HttpSessionBindingEvent sessionBindingEvent) {
		String name = sessionBindingEvent.getName();
		Object value = sessionBindingEvent.getValue();
		System.out.println("有属性在移除!"+name+"-->"+value);
		
	}

	// 属性替换
	@Override
	public void attributeReplaced(HttpSessionBindingEvent sessionBindingEvent) {
		String name = sessionBindingEvent.getName();
		Object value = sessionBindingEvent.getValue();
		System.out.println("有属性在替换!"+name+"-->"+value);
	}

}
  • 在web.xml中配置

    <listener>
    	<listener-class>cn.kgc.demo1.MyListener1</listener-class>
    </listener>
    

感知型监听器

  • 在需要感知的类型上去实现对应的接口

  • 实现对应的感知方法即可

    public class User implements Serializable,HttpSessionBindingListener{
    
    	private static final long serialVersionUID = 1L;
    
    	private String username;
    	private String password;
    	
    	// 省略getter/setter和构造
    	
    	@Override
    	public String toString() {
    		return "User [username=" + username + ", password=" + password + "]";
    	}
    	
    	// 当用户类型对象被绑定时触发 
    	// session.setAttribute();
    	@Override
    	public void valueBound(HttpSessionBindingEvent event) {
    	//获取值
    		Object value = event.getValue();
    		User loginUser = (User)value;
    		System.out.println("用户:"+loginUser.getUsername()+"上线了!");
    	}
    	
    	// 当用户类型对象被解绑时触发
    	@Override
    	public void valueUnbound(HttpSessionBindingEvent event) {
    		Object value = event.getValue();
    		User loginUser = (User)value;
    		System.out.println("用户:"+loginUser.getUsername()+"下线了!");
    	}
    	
    }
    
    
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值