Filter&Listener
1.Web三大件
Servlet,Filter,Listener
2.Filter过滤器
2.1概念
Filter 过滤器它是 JavaEE 的规范。也就是接口
Filter 过滤器它的作用是:拦截请求,过滤响应
2.2案例
服务器中的资源--》 图片,css,js,音频视频,html,jsp 等都是资源
2.2.1第一步:编写一个Filter 通过实现Filter接口
package com.qfedu.filter;
import javax.servlet.*;
import java.io.IOException;
public class Demo01Filter implements Filter {
// init 方法 ==-》 Filter创建的时候调用
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("我被创建了....");
}
// 当程序被拦截器拦截之后,会执行doFilter里面的代码
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("这是我的第一个过滤器");
// 获取到资源之后,根据条件选择是否放行
filterChain.doFilter(servletRequest,servletResponse);
}
// filter即将回收的时候调用
@Override
public void destroy() {
System.out.println("我即将被回收");
}
}
这个里面有三个方法:
init --> 该Filter被创建的时候调用,只调用一次
destory--> 该Filter对象被销毁的时候调用,也只调用一次
doFilter --> 核心方法,过滤器没拦截一次请求,就执行一次方法。
不管是做什么操作,记得放行:
filterChain.doFilter(servletRequest,servletResponse);
2.2.2第二步: 配置Filter
- 在web.xml中编写xml
<filter>
<filter-name>filter01</filter-name>
<filter-class>com.qfedu.filter.Demo01Filter</filter-class>
</filter>
<filter-mapping>
<filter-name>filter01</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
2)注解的方案: @WebFilter("/*")
2.2.3过滤器拦截规则和执行顺序
执行顺序:
浏览器 --> 过滤器去拦截 --> 获取资源 --> 又到 过滤器这里--> 过滤器放行-->浏览器展示资源
问题:如果有两个 过滤器,都满足拦截条件,先执行哪个,后执行哪个?
1、如果你是注解配置的方式编写的过滤器:执行顺序按照类名进行比较
AFilter BFilter A先执行,B后执行
A10Filter A2Filter 先执行A10Filter ,后执行A2Filter.
2、web.xml方式编写的配置
定义在最前面的,先执行,定义在后面的后执行
一个项目中,要么都使用xml,要么都使用注解,所以注解和xml混着写的方式一般不存在。
拦截的规则有如下几种写法:
1、拦截具体的路径 /index.jsp 只拦截index.jsp
2、拦截目录: /customer/* 只拦截以customer开头的二级访问路径
3、拦截以某种后缀名结尾的请求 *.do *.action .jsp
4、拦截所有请求 /
在过滤器中,还可以设置拦截被访问的方式 DispatcherType 【了解】
DispatcherType
- REQUEST: 默认值,拦截浏览器直接请求的资源,类似于重定向
- FORWARD: 内部转发 只拦截内部转发的资源
- INCLUDE: 一个资源被包含在另一个资源中,发出的请求
-
ERROR: 错误跳转的资源
-
ASYNC: 异步访问的资源
2.3实战
通过过滤器实现,只有登录后才能访问操作系统中的资源
package com.qfedu.filter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
@WebFilter({"/customer/*"})
public class LoginFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
// ServletRequest 是 HttpServletRequest的父类
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("进入到登录过滤器");
HttpServletRequest req = ((HttpServletRequest) servletRequest);
// 先判断该用户有没有登录,如果没有登录,直接跳转到登录页面
HttpSession session =req.getSession();
Object obj = session.getAttribute("USERNAME");
if(obj!=null){
// 如果判断登录过了,直接放行
filterChain.doFilter(servletRequest,servletResponse);
}else{
// 没有登录过,跳转到登录页面
((HttpServletResponse)servletResponse).sendRedirect(req.getContextPath()+"/login.jsp");
}
}
@Override
public void destroy() {
}
}
字符集的一个设置:
我们有很多页面,都需要设定字符集,防止中文乱码 编写一个字符集过滤器,为指定的servlet设置字符集,以后就不用我们设置了。
3.Listener--> 监听器
Java Web监听器很多中,最常用的,以后能用的上的,就这一种:ServletContextListener
监听ServetContext的诞生的。
如果ServletContext对象被创建了,就会触发ServletContextListener中的代码。
ServletContext对象有什么用,它创建不创建跟我的代码有什么关系?
ServletContext对象是在tomcat已启动就被创建的,被tomcat所创建。
换句话说:当一个项目已启动就会触发ServletContextListerner.
我们可以将项目启动时需要加载的数据或者资源放入到该ServletContextListener中。
项目中的真实案例:
群发短信功能---> 每一个手机号码都需要进行一个红名单的校验
红名单:此类手机号码千万不要给它发垃圾短信。
红名单的数据在你们公司的数据库中,大约有100多万条。
发短信要校验红名单。
项目一启动,就开始查询红名单数据,将数据存放在内存中,将来拿到一个手机号去校验是否是红名单数据就非常快。
代码演示
package com.qfedu.listener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
@WebListener
public class ContextLoaderListener implements ServletContextListener {
//监听ServletContext被创建就执行如下代码
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
System.out.println("servletContext被创建了");
}
//监听ServletContext被销毁,触发如下代码
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
System.out.println("servletContext被销毁了");
}
}
Listener编写完之后也有两种配置方案
xml
<listener>
<listener-class>com.qfedu.listener.ContextLoaderListener</listener-class>
</listener>
注解方案: @WebListener
监听器什么时候执行,不是由我们决定的,而是监听器本身监听的对象决定,监听器监听的对象发生改变了,监听器中的代码就自动执行了。一个对象,同一个动作一般只有一个监听器。我们学习的是ServletContextListener!
4.总结三大组件
1、web.xml中都可以写什么内容?
项目中的web.xml其实是tomcat服务器中web.xml的子集。它可以配置servlet,Filter,Listener
welcome-file-list 设置欢迎页,还可以设置一些参数 context_param。
2、各个组件之间的执行顺序说一下?
web.xml中加载顺序:--> listener --> filter --> servlet
filter如果是多个,加载顺序怎样。
servlet很多,加载顺序如何?load-on-startup 有关系。
3、三大组件共同的特点
编写完代码之后,必须进行配置,配置都分为两种 xml 和 注解