此次通过学习,学到了Filter过滤器,感觉挺有意思的,在学习JavaWeb时也是一个比较重要的内容。
2.10 Filter过滤器
1、Filter过滤器是javaweb的三大组件之一。三大组件分别是:Servlet、Listener、Filter
2、Filter是javaEE的规范。它是接口
3、Filter过滤器的作用是:拦截请求和过滤响应。
拦截请求常用的应用场景有:
- 权限检查
- 日记操作
- 事务管理等
2.10.1 Filter过滤器的基本使用实例
要求在web工程下,有一个admin目录,admin目录下的所有资源(html页面、jpg图片、jsp文件等)都必须是用户登陆之后才允许访问。
检查用户是否登录,只用检查Session域对象
这个是写在admin目录下的jsp文件(因为课程原因,只能学淘汰的jsp技术,等过了这段时间就去看22版的javaweb尚硅谷的视频,继续更新最新知识)
<%
Object user = request.getSession().getAttribute("user");
//如果等于null,则还没有登录
if (user==null){
request.getRequestDispatcher("/login.jsp").forward(request,response);
return;
}
%>
这种方法存在局限性,则需要使用Filter
这是对Filiter的图解
web.xml文件中的filter配置,此处使用的目录匹配,具体之后会提到
<!--filter标签用于配置一个Filter过滤器 -->
<filter>
<!-- filter-name:给Filter取别名 -->
<filter-name>Adminter</filter-name>
<!-- filter-class:配置Filter的全类名 -->
<filter-class>com.sakura.Filter.Adminter</filter-class>
</filter>
<!-- filter-mapping:配置Filter的拦截路径 -->
<filter-mapping>
<!-- filter-name:表示当前的拦截路径个那个filter使用 -->
<filter-name>Adminter</filter-name>
<!-- url-pattern:配置Filter的拦截路径
/admin/*表示请求地址,映射到web下的admin下的全部目录
-->
<url-pattern>/admin/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>类名</filter-name>
<filter-class>全类名</filter-class>
</filter>
<filter-mapping>
<filter-name>类名</filter-name>
<url-pattern>/映射到的web目录下的jsp或者html页面</url-pattern>
</filter-mapping>
代码如下:
类实现Filter接口,实现doFilter方法,写在src目录下,实现Filter接口
/**
* doFilter专门用于拦截请求,可以做权限检查
* @param servletRequest
* @param servletResponse
* @param filterChain
* @throws IOException
* @throws ServletException
*/
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//因为Filter中没有HttpServletRequest,则需要对ServletRequest进行强转
HttpServletRequest httpServletRequest=(HttpServletRequest) servletRequest;
HttpSession session=httpServletRequest.getSession();
Object user =session.getAttribute("user");
//如果等于null,则还没有登录
if (user==null){
httpServletRequest.getRequestDispatcher("/login.jsp").forward(servletRequest,servletResponse);
return;
}else{
//让程序继续往下访问用户的目标资源
filterChain.doFilter(servletRequest,servletResponse);
}
}
该代码是,只要检测到session中的user为null,就会跳转到login.jsp注册页面,如果已经注册则可以跳转到a.jsp或者a.html
2.10.2 Filter完整的用户登录和权限检查
Filter过滤器的使用步骤:
- 编写一个类去实现Filter接口
- 实现过滤方法doFiliter()
- 到web.xml中配置Filter的拦截路径
登录界面,当访问admin下的文件时,只要没有注册,则会跳转到登录界面
对登录界面的内容进行判断,用户名和密码是否正确,如果错误,则再次返回登录界面
当a.jsp被访问,但是没有登录,则此时,会跳转到b.jsp页面,直到登录成功则可以输出“我是a.jspx”
filterChain.doFilter(servletRequest,servletResponse);
这行代码十分重要,只有有了这行代码才能继续访问到用户接下来的资源
2.10.3 Filter的生命周期
Filter的生命周期包含几个方法:
- 构造器方法
- init初始化方法
第一、二步在web工程启动的时候就已经执行(Filter已经创建
- doFilter过滤方法
doFilter每次拦截到请求会就执行
- destroy销毁方法
在停止web工程的时候,就会执行(停止web工程也会销毁Filter过滤器)
2.10.4 FilterConfig类
是Filter过滤器的配置文件夹。
Tomcat每次创建Filter的时候,也会同时创建一个FilterConfig类,这里包含了Filter配置文件的配置信息。
FilterConfig类的作用获取filter过滤器的配置内容
- 获取Filter的名称:filter-name的内容
- 获取在Filter中配置的init-param初始化参数
- 获取ServletContext对象
// 1、 获取Filter的名称:filter-name的内容
System.out.println("filter-name的值是:" + filterConfig.getFilterName());
// 2、 获取在Filter中配置的init-param初始化参数
System.out.println("初始化参数username的值是:"+filterConfig.getInitParameter("username"));
System.out.println("初始化参数url的值是" + filterConfig.getInitParameter("url"));
// 3、 获取ServletContext对象
System.out.println(filterConfig.getServletContext());
2.10.5 FilterChain多个过滤器执行的细节
Filter 过滤器
Chain 链、链条
FilterChain 过滤器链(多个过滤器如何一起工作)
这是对多个过滤器的工作原理的图解注释
主要是使用FilterChain.doFilter()实现多个过滤器的共同执行
创建两个
Filter其中的doFilter中内置的代码格式都如下
最后在控制台如下展示:
在多个Filter过滤器执行的时候,他们执行的优先顺序是由他们在web.xml中从上到下配置的顺序决定!
eg:如果此时将Filter2在web.xml提到Filter1之前,则在控制台上输出结果为:
Filter2的前置代码
Filter1的前置代码
target.jsp页面执行了
Filter1的后置代码
Filter2的后置代码
多个Filter过滤器执行的特点:
- 所有Filter和目标资源默认都执行在同一个线程中
- 多个Filter共同执行的时候,他们都是用同一个Request对象。
2.10.6 Filter的拦截路径
——精准匹配
<url-pattern>/target.jsp</url-pattern>
以上配置的路径,表示请求地址必须为:http://ip:port/工程路径/target.jsp
才能拦截到
——目录匹配
<url-pattern>/admin/*</url-pattern>
以上配置的路径,表示请求地址必须为:http://ip:port/工程路径/目录/* 才能拦截到
——后缀匹配
<url-pattern>*.jsp</url-pattern>
以上配置路径,表示请求地址必须以.文件类型结尾才能拦截到
Filter过滤器只关心请求的地址是否匹配,不关心请求的资源是否存在!