过滤器和监听器

过滤器和监听器

 

1.过滤器

1.1)简介

 

过滤器也称之为拦截器,是Servlet2.3规范中新增的功能,在servlet2.4规范中得到了增强。过滤器是servlet中非常实用的技术,可以在用户访问某个web资源之前,对访问的请求和响应进行拦截,从而实现一些特殊的功能。例如:验证用户访问权限,记录用户操作,对请求进行重新编码和压缩响应信息等。

原理:当用户的请求到达请求的资源之前,可借助过滤器来改变一些请求的内容,此过程叫做预处理。当执行结果返回到用户之前,可经过过滤器来修改响应,这个叫后处理。过滤器运行过程中有一下步骤;

  • Web容器判断请求的资源是否有相匹配的过滤器,如果有,就交。
  • 过滤器进行预处理,完事儿发给目标资源
  • 目标资源对请求做出响应
  • 容器将响应返回给过滤器
  • 过滤器进行后处理
  • Web容器将响应发回客户端

 

 

在一个web应用中,可以创建多个过滤器,形成过滤器连=链,每一个都有特殊的功能。在请求响应的过程中,并不需要经过所有的过滤器链,而是根据过滤器链中每个过滤器的条件来匹配需要过滤的资源。

1.2)过滤器核心接口

 

1.Filter接口

Filter定义了三个方法

 

方法

描述

Init(Filter config)

过滤器的初始化方法

doFilter(request,response,FilterChain chain)

过滤器功能实现

destroy()

生命周期结束时由web容器调用,释放资源

 

 

过滤器的生命周期分为4个阶段。

  1. 加载和实例化。

Web启动的时候会根据@WebFilter属性的filterName所定义的类名的字符拼写顺序,或者web.xml中声明的filter顺序依次实例化Filter

 

  1. 初始化

Web容器调用init()方法来初始化过滤器 该方法传入一个Filterconfig对象,初始化只进行一次。

 

  1. doFilter()方法的执行

当客户端请求目标资源的时候,容器会根据@WebFilter属性的filterName指定的过滤器依次调用相应的过滤器。的doFilter方法。在这个链式的过程中,可以调用FilterChain对象的doFilter()方法将请求发给下一个过滤器或者目标资源,或者直接响应,或者请求转发到其他资源。。过滤器的使用不依赖于协议,,请求响应参数是ServletRequest和ServletResponse

 

  1. 销毁

Web容器调用destroy()方法指示过滤器的声明周期结束。在这个方法中可以释放过滤器使用的资源。

 

2.FilterConfig接口

 

容器将实例作为参数传入过滤器对象的初始化方法init()中,来获取过滤器的初始化参数和Servlet的相关信息。

方法

描述

getFilterName()

获取配置信息中指定的过滤器名字

getInitParameter(String name)

获取配置信息中指定的名为name的过滤器初始化参数值

geiInitParameterNames()

获取过滤器的所有初始化参数的名字的枚举集合

getServletContext()

获取Servlet上下文集合

 

3.FilterChain接口

该接口由容器实现,容器将其实例作为参数传入过滤器对象的doFilter()方法中。过滤器对象使用FilterChain对象调用过滤器链中的下一个过滤器,如果该过滤器是链中最后一个过滤器,那么将调用目标资源。

 

doFilter(ServletRequest request,ServletResponse response)  该方法将使用过滤器链中的下一个过滤器被调用,如果是最后一个过滤器,则调用目标资源。

 

 

 

 

1.3)过滤器的开发

 

  1. 创建一个Filter接口的实现类

Eclipse中   New--->Filter,eclipse会自动创建,init、doFilter()、destroy  方法,这是Filter的必备条件

 

 

 

2.编写过滤器功能代码

下面过个实现一个对请求和响应过程计时的功能。

 

import java.io.IOException;
import java.util.Date;
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;
import javax.servlet.annotation.WebInitParam;

@WebFilter(urlPatterns = {"/*"}, initParams = {@WebInitParam(name = "param", value = "xxxxx")})
public final class ExampleFilter implements Filter {
    private String attribute = null;
    private FilterConfig filterConfig = null;
    public void init(FilterConfig fConfig) throws ServletException {
        this.filterConfig = fConfig;
        this.attribute = fConfig.getInitParameter("param");
        filterConfig.getServletContext().log(
                "获得初始化参数param的值为:" + this.attribute);
    }
    @Override
    public void destroy() {
        this.attribute = null;
        this.filterConfig = null;
    }
    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
                         FilterChain chain) throws IOException, ServletException {
        long startTime = System.currentTimeMillis();
        filterConfig.getServletContext().log(
                new Date(startTime) + "请求经过" + this.getClass().getName()
                        + "过滤器");
        chain.doFilter(request, response);
        long stopTime = System.currentTimeMillis();
        filterConfig.getServletContext().log(
                new Date(stopTime) + "响应经过" + this.getClass().getName()
                        + "过滤器,本次请求响应过程花费 " + (stopTime - startTime) + " 毫秒");


    }

}

 

 

 

 

3.对过滤器进行声明配置

@WebFilter(urlPatterns = {“/*”},initParams = {@WebInitParam(name = “param”,value = “xxxx”)})

 

上面代码用于将一个类声明为Filter,同时进行属性配置,改配置表示对本应用的所有请求使用此过滤器进行过滤拦截,同时在过滤器初始化时传递初始化参数param。

Filter常用的属性如下:

方法

描述

FilterName

Filter的名称,默认类名

urlPatterns

必有的属性,指所拦截的url

ServletName

用于指定对那些servlet进行过滤

dispatcherTypes

用于指定该Filter对那些模式的请求进行过滤

 

 

1.4)过滤器的应用

 

 

过滤器有很多实用的技术,也得到了广泛的使用。

  • 做统一认证处理
  • 对用户的请求进行检查和更精确的记录
  • 监听或对用户所传递的参数做前置处理,如防止数据注入攻击
  • 改变图像文件的格式
  • 对请求和响应进行编码
  • 对响应做压缩处理
  • 对xml的输出使用XSLT来转换

 

  1. 批量设置请求编码

 


 

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 SetCharacterEncodingFilter implements Filter {
    String encoding;
    public SetCharacterEncodingFilter() {
    }

    public void init(FilterConfig fConfig) throws ServletException {
// 获取过滤器配置的初始参数
        this.encoding = fConfig.getInitParameter("encoding");
    }
    public void destroy() {
        this.encoding = null;
    }
    public void doFilter(ServletRequest request, ServletResponse response,
                         FilterChain chain) throws IOException, ServletException {
        if (encoding == null)
            encoding = "UTF-8";
// 设置请求的编码
        request.setCharacterEncoding(encoding);
// 过滤传递
        chain.doFilter(request, response);
    }
}



 

  1. 控制用户访问权限

 

 


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;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

/**

  * 控制用户对某些请求地址的访问权限

  */

@WebFilter(urlPatterns = { "/*" }, initParams = {
        @WebInitParam(name = "loginPage", value = "login.jsp"),
        @WebInitParam(name = "loginServlet", value = "LoginProcessServlet") })
public class SessionCheckFilter implements Filter {
// 用于获取初始化参数
    private FilterConfig config;
    public SessionCheckFilter() {

    }
    public void init(FilterConfig fConfig) throws ServletException {
        this.config = fConfig;
    }
    public void destroy() {

        this.config = null;

    }
    public void doFilter(ServletRequest request, ServletResponse response,
                         FilterChain chain) throws IOException, ServletException {
// 获取初始化参数
        String loginPage = config.getInitParameter("loginPage");
        String loginServlet = config.getInitParameter("loginServlet");
// 获取会话对象
        HttpSession session = ((HttpServletRequest) request).getSession();
// 获取请求资源路径(不包含请求参数)
        String requestPath = ((HttpServletRequest) request).getServletPath();
        if (session.getAttribute("user") != null
                || requestPath.endsWith(loginPage)
                || requestPath.endsWith(loginServlet)) {
// 如果用户会话域属性user存在,并且请求资源为登录页面和登录处理的Servlet,则“放行”请求
            chain.doFilter(request, response);
        } else {
// 对请求进行拦截,返回登录页面
            request.setAttribute("tip", "您还未登录,请先登录!");
            request.getRequestDispatcher(loginPage).forward(request, response);
        }
    }
}

 

 

 

 

 

2.监听器

2.1)简介

 

Servlet API提供了大量监听器接口来帮助开发者实现对web应用内特定事件进行监听从而当web应用内这些特定事件发生时,回调监听器内的事件监听器方法来实现一些功能。

 

 

实现监听器需要通过两个步骤:

【步骤一】

定义监听器类,实现监听器接口的所有方法

【步骤二】

通过Annotation或者在web.xml文件中声明Listener

 

创建Listener时,需要使用@WebListener对监听进行声明,注解@WebListener的常用属性如下:

 

@WebListener(“描述信息”)

 

2.2)与servlet上下文相关的监听器

 

监听器接口名称

说明

ServletContextListener

用于监听ServletContext对象的创建和销毁

ServletContextAttributeListener

用于监听ServletContext范围内属性的改变

 

 

1.ServletContextListener

  1. contextInialized(ServletContextEvent sce)当servletContext对象创建时,web容器将调用此方法。该方法接受ServletContextEvent事件对象,通过此对象可获得当前被创建的ServletContext对象,通过此对象可获得当前被创建的ServletContext对象
  2. contextDestroyed(ServletContextEvent sce)当ServletContext对象被销毁是执行

 

 

 

2.ServletContextAttributeListener

 

  1. attributeAdded(ServletContextAttributeEvent event)当程序把一个属性存入到application中时执行此方法
  2. attributeRemoved(ServletContextAttributeEvent event)当程序把一个属性从application范围中删除时
  3. attributeReplaced(ServletContextAttributeEvent event)当程序替换application范围内的属性时。

 

 

 

2.3)与会话相关的监听器

 

监听器接口

说明

HttpSessionListener

用于监听会话对象的创建和销毁

HttpSessionAttributeListener

用于监听会话域内属性的改变

 

 

1.HttpSessionListener

  1. sessionCreated(HttpSessionEvent event)当HttpSession对象被创建时,web容器调用此方法
  2. sessionDestroyed(HttpSessionEvent se)当httpsession被销毁时,执行该代码

 

2.HttpSessionAttributeListener

 

  1. AttributeAdded(HttpSessionAttributeEvent event)当程序把一个属性存入session范围时
  2. AttributeRemoved(HttpSessionAttributeEvent event)当属性从session中删除时
  3. AttributeReplaced(HttpSessionAttributeEvent event)当程序替换session范围中的属性时

 

2.4)与请求相关的监听器

监听器接口

说明

ServletRequestListener

用于监听用户请求的产生和结束

ServletRequestAttributeListener

用于监听ServletRequest(requset)范围内的属性

 

 

1.ServletRequestListener

  1. requestInitialized(ServletRequestEvent event)当ServletRequest对象被创建时
  2. RequestDestroyed(ServletRequsetEvent event)当ServletResquset对象被销毁时

 

2.ServletRequestAttributeListener

  1. arributeAdded(ServletRequestAttributeEvent event)当程序把一个属性存入requset范围中时
  2. attributeRemoved(ServletRequestAttributeEvent event)当程序吧一个属性从request范围中删除时。
  3. attributeReplaced(ServletRequestAttributeEvent event)当程序替换一个属性时
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值