过滤器和监听器

过滤器和监听器

Servlet过滤器和监听器

Filter过滤器概述

当客户端访问服务器的资源时,过滤器可以将请求拦截下来,完成一些特殊的功能。举个例子帮助大家理解:比如2020年初在爆发了新冠病毒疫情,为了防止病毒扩算到全国,武汉市宣布封城,所有交通渠道限制通行,在各个出入口设卡拦截,只有体温正常的医务人员和急救物资才能进入城区。这里武汉市各个出入口的关卡,起到的就是过滤器的作用。

在程序中是同样的道理,比如用户在访问服务器资源时只允许登录过的用户才能正常访问。这里登录校验起到的就是过滤器的作用。除了登录校验,在程序中过滤器的用处还有统一编码处理,铭感词汇过来

过滤器快速入门

过滤器步骤

1. 定义一个类,实现接口Filter
2. 复写方法
3. 配置拦截路径
    web.xml配置
    注解配置

代码实现

// /*: 访问所有资源之前,都会执行该过滤器
@WebFilter("/*")
public class FilterDemo1 implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("filterDemo1被执行了....");
        //放行
        filterChain.doFilter(servletRequest,servletResponse);
    }

    @Override
    public void destroy() {

    }
}

浏览器访问 http://localhost:8080/FilterListener/index.jsp 查看控制台输出结果,会发现在过滤器执行了两次。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nUEd2lBx-1684336061687)(/Volumes/T7 Shield/assets/8、Filter和Listener/20211210153143.png)]

过滤器web配置

上面的案例采用web.xml方式进行配置效果是一样的

<filter>
     <filter-name>FilterDemo1</filter-name>
     <filter-class>com.itheima.FilterDemo1</filter-class>
</filter>

<filter-mapping>
    <filter-name>FilterDemo1</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

浏览器访问 http://localhost:8080/FilterListener/index.jsp 查看控制台输出结果,会发现在过滤器执行了两次。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9ObiION5-1684336061687)(/Volumes/T7 Shield/assets/8、Filter和Listener/20211210153152.png)]

过滤器执行流程
1. 执行过滤器
2. 执行放行后的资源
3. 回来执行过滤器放行代码下边的代码
过滤器生命周期
1. init:在服务器启动后,会创建Filter对象,然后调用init方法。只执行一次。用于加载资源
2. doFilter:每一次请求被拦截资源时,会执行。执行多次
3. destroy:在服务器关闭后,Filter对象被销毁。如果服务器是正常关闭,则会执行destroy方法。只执行一次。用于释放资源
过滤器配置详解

拦截路径配置

1. 具体资源路径: /index.jsp 
    只有访问index.jsp资源时,过滤器才会被执行
2. 拦截目录: /user/*    
    访问/user下的所有资源时,过滤器都会被执行
3. 后缀名拦截: *.jsp        
    访问所有后缀名为jsp资源时,过滤器都会被执行
4. 拦截所有资源:/*        
    访问所有资源时,过滤器都会被执行

拦截方式配置

【注解配置】:设置dispatcherTypes属性
    1. REQUEST:默认值。浏览器直接请求资源
    2. FORWARD:转发访问资源
    3. INCLUDE:包含访问资源
    4. ERROR:错误跳转资源
    5. ASYNC:异步访问资源         
【web.xml配置】
    设置<dispatcher></dispatcher>标签即可

看下面的注解配置的举例

//直接请求http://localhost:8080/FilterListener/index.jsp时,被过滤器拦截
@WebFilter(value = "/index.jsp",dispatcherTypes = DispatcherType.REQUEST)

//请求转发到http://localhost:8080/FilterListener/index.jsp,被过滤器拦截
@WebFilter(value = "/index.jsp",dispatcherTypes = DispatcherType.FORWARD)

过滤器链(配置多个过滤器)

执行顺序:如果有两个过滤器:过滤器1和过滤器2
    1. 过滤器1
    2. 过滤器2
    3. 资源执行
    4. 过滤器2
    5. 过滤器1 

过滤器先后顺序问题:
    1. 注解配置:按照类名的字符串比较规则比较,值小的先执行
        * 如: AFilter 和 BFilter,AFilter就先执行了。
    2. web.xml配置: <filter-mapping>谁定义在上边,谁先执行

案例1:登录验证

需求:
1. 访问UserManager案例的资源。验证其是否登录
2. 如果登录了,则直接放行。
3. 如果没有登录,则跳转到登录页面,提示"您尚未登录,请先登录"

img

//设置拦截路径为所有路径
@WebFilter("/*")
public class LoginFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        //获取请求的uri
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

        String uri = request.getRequestURI();
        //当uri是请求登录、js、css、font、验证码资源时放行
        if(uri.contains("/login.jsp")||uri.contains("/LoginServlet")||uri.contains("/js")||uri.contains("css")||uri.contains("fonts")||uri.contains("/VerificationCodeServlet")){
            filterChain.doFilter(request,servletResponse);
        }else{
            //否则,判断是否登录
            Object loginUser = request.getSession().getAttribute("loginUser");
            if(loginUser==null){
                //如果没有登录,跳转到登录页面
                response.sendRedirect(request.getContextPath()+"/login.jsp");
            }else {
                //如果有登录,直接放行
                filterChain.doFilter(request,servletResponse);
            }
        }
    }

    @Override
    public void destroy() {

    }
}

案例2:敏感词汇过滤

* 需求:
    1. 对users案例录入的数据进行敏感词汇过滤
    2. 敏感词汇参考《敏感词汇.txt》
    3. 如果是敏感词汇,替换为 *** 

* 分析:
    1. 对request对象进行增强。增强获取参数相关方法
    2. 放行。传递代理对象

Servlet监听器

Listener监听器是web的三大组件之一。

* 事件监听机制
    * 事件    :一件事情
    * 事件源 :事件发生的地方
    * 监听器 :一个对象
    * 注册监听:将事件、事件源、监听器绑定在一起。 当事件源上发生某个事件后,执行监听器代码

ServletContextListener接口

ServletContextListener用来监听ServletContext对象的在创建和销毁时所做的事情。

public void contextDestroyed(ServletContextEvent sce) 
    ServletContext对象被销毁之前会调用该方法
public void contextInitialized(ServletContextEvent sce) 
    ServletContext对象创建后会调用该方法

步骤

1. 定义一个类,实现ServletContextListener接口
2. 复写方法
3. 配置方式
    1. web.xml
            <listener>
                <listener-class>cn.itcast.web.listener.ContextLoaderListener</listener-class>
            </listener>

            * 指定初始化参数<context-param>
    2. 注解:
        * @WebListener
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值