JSP三大组件之监听器和过滤器

监听器(Listener)

**理解:**监听器就是对项目起到监听的作用,它能感知到包括request(请求域),session(会话域)和applicaiton(应用程序)的初始化和属性的变化;

web监听器是Servlet中一种特殊的类,能监听web中的特定时间,比如ServletContext,HttpSession,ServletRequest的创建和销毁;变量的创建、销毁和修改等。可以在某些动作前后增加处理,实现监控。

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

1、 监听器接口和注册

​ 监听器接口主要在 javax.servlet 和 javax.servlet.http 的包中。对应上文的三类,有以下这些接口:

​ 第一类:

名称作用
javax.servlet.ServletContextListener它能响应Servlet生命周期事件,它提供了ServletContext创建之后和ServletContext关闭之前的会被调用的方法。
javax.servlet.http.HttpSessionListener它能响应HttpSession的创建、超时和失效事件。
javax.servlet.http.HttpActivationListener它在一个HttpSession激活或者失效时被调用。
javax.servlet.ServletRequestListener它能响应一个ServletRequest的创建或删除。

​ 第二类:

名称作用
javax.servlet.ServletContextAttributeListener它能响应ServletContext范围内的属性添加、删除、替换事件。
javax.servlet.http.HttpSessionAttributeListener它能响应HttpSession范围内的属性添加、删除、替换事件。
javax.servlet.http.HttpSessionBindingListener可以实现这个接口来保存HttpSession范围的属性。当有属性从HttpSession添加或者删除时,它能做出响应。
javax.servlet.ServletRequestListener它能响应ServletRequest范围的属性添加、删除、修改事件。

2、Listener部署

编写一个监听器,只需要写一个Java类来实现对应的监听器接口就可以了。在Servlet 3.0和Servlet 3.1中提供了两种注册监听器的方法。一种是使用WebListener注解。例如:

@WebListener
public class ListenerClass implements ListenerInterface {
}

​ 第二种是在部署描述文档中增加一个listener元素。

<listener>
    <listener-class>fully-qualified listener class</listener-class>
</listener>

3、listener实际应用

  • 统计在线人数,利用HttpSessionLisener
  • 加载初始化信息:利用ServletContextListener
  • 统计网站访问量、实现访问监控等

获取当前在线人数

package com.mycompany.mvc.listener;  
  
import javax.servlet.http.HttpSessionEvent;  
import javax.servlet.http.HttpSessionListener;  
  
public class myHttpSessionListener implements HttpSessionListener{  
  
    public static int peopleOnLine = 0;  
      
    @Override  
    public void sessionCreated(HttpSessionEvent hse) {  
        System.out.println("myHttpSessionListener.sessionCreated():"+hse);  
        peopleOnLine++;  
        hse.getSession().setAttribute("peopleOnLine",peopleOnLine);  
    }  
  
    @Override  
    public void sessionDestroyed(HttpSessionEvent hse) {  
        System.out.println("myHttpSessionListener.sessionDestroyed():"+hse);  
        peopleOnLine--;  
        hse.getSession().setAttribute("peopleOnLine",peopleOnLine);  
    }  
} 
<%=session.getAttribute("peopleOnLine")%>  

过滤器(Filters)

过滤器是Servlet的高级特性之一,也别把它想得那么高深,只不过是实现Filter接口的Java类罢了!

当浏览器发送请求给服务器的时候,先执行过滤器,然后才访问Web的资源。服务器响应Response,从Web资源抵达浏览器之前,也会途径过滤器。。

过滤器可以比喻成一张滤网。我们想想现实中的滤网可以做什么:在泡茶的时候,过滤掉茶叶。那滤网是怎么过滤茶叶的呢?规定大小的网孔,只要网孔比茶叶小,就可以实现过滤了!

引申在Web容器中,过滤器可以做:过滤一些敏感的字符串【规定不能出现敏感字符串】、避免中文乱码【规定Web资源都使用UTF-8编码】、权限验证【规定只有带Session或Cookie的浏览器,才能访问web资源】等等等,过滤器的作用非常大,只要发挥想象就可以有意想不到的效果

过滤器其实也是责任链模式的一种实现,FilterChain层层往下执行,直到最后没有过滤器,就到了「目标资源」

**理解:**就是对请求起到过滤的作用,它在监听器之后,作用在servlet之前,对请求进行过滤;

1、Filter API

Filter的实现必须继承 javax.servlet.Filter 接口。这个接口包含了 Filter 的三个生命周期:init,doFilter,destroy。

Servlet容器初始化 Filter 时,会触发 Filter 的 init 方法,一般在应用开始时,而不是在相关资源使用时才初始化,这个方法只调用一次。init 定义如下:

void init(FilterConfig filterConfig)

​ 当Servlet 容器每次处理Filter相关资源时,都会调用该Filter实例的doFilter方法。doFilter包含三个参数,定义如下:

void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)

​ 在doFilter中可以访问ServletRequest、ServletResponse。

​ 在Filter的doFilter的实现中,最后一行需要调用FilterChain 中的 doFilter 方法。注意Filter的doFilter方法里的第三个参数,就是filterChain的实例:

filterChain.doFilter(request, response)

2、Filter部署

第一种方式:在web.xml文件中配置

<filter>
    //用于为过滤器指定一个名字,该元素的内容不能为空。
    <filter-name>FilterDemo1</filter-name>
	//元素用于指定过滤器的完整的限定类名。
    <filter-class>FilterDemo1</filter-class>
</filter>

//<filter-mapping>元素用于设置一个Filter 所负责拦截的资源
<filter-mapping>
    //用于设置filter的注册名称。该值必须是在元素中声明过的过滤器的名字
    <filter-name>FilterDemo1</filter-name>
    //设置 filter 所拦截的请求路径(过滤器关联的URL样式)
    <url-pattern>/*</url-pattern>
</filter-mapping>

第二种方式:通过注解配置

@WebFilter(urlPatterns = {"*.jsp","*.do"})

2.1 Filter的配置详解

  • 具体的资源路径
/index.jsp

只有访问index.jsp的时候,过滤器才会被执行
  • 拦截目录
/user/*

访问/user目录下的所有资源的时候,过滤器才会被执行
  • 后缀名拦截
*.jsp

访问所有jsp页面都会被拦截
  • 拦截所有资源
/*

3、Filter实际应用

一般用于完成通用的操作。如:登录验证、统一编码处理、敏感字符过滤……

编码过滤器(解决乱码的问题)

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("-----filterEncoding dofillter----");
         //将request和response强转成http协议的
        HttpServletRequest request = (HttpServletRequest)servletRequest;
        HttpServletResponse response = (HttpServletResponse)servletResponse;


        request.setCharacterEncoding("utf-8");
        response.setCharacterEncoding("utf-8");
        response.setContentType("text/html; charset=UTF-8");
        // 放行,转到下一个过滤器
        filterChain.doFilter(request, response);
    }
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值