01学习目标
- 能够说出过滤器的作用
- 能够编写过滤器
- 能够说出过滤器生命周期相关方法
- 能够根据过滤路径判断指定的过滤器是否起作用
- 能够说出什么是过滤器链
- 能够编写过滤器解决全局乱码
02.过滤器介绍与应用场景【理解】
目标
掌握过滤器的作用与应用场景
为什么学习过滤器
浏览器提交post传递中文数据给不同的Servlet去处理,那所有接收post中文数据的Servlet都要处理乱码,非常麻烦。可以使用一种拦截请求的方式,拦截所有Servlet的请求,进行集中对中文乱码处理,处理完成以后再去各自的目标Servlet, 这样每个Servlet就不用处理乱码。那么这个拦截所有Servlet的请求就是过滤器。
过滤器介绍
过滤器是javaEE体系提供的一个Filter接口,我们只需要实现Filter接口就可以拦截任意的请求与响应。
过滤器的作用
拦截请求与响应
应用场景介绍
-
解决post提交中文乱码应用场景
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UtcfDueO-1606226675658)(assets/image-20200508093708142.png)]
-
登录权限控制
需求:服务器某一类资源(很多资源)需要登录后才可以访问,就是登录权限控制
传统解决方案:访问这一类中每个资源都要判断是否登录,登录了允许访问,否则return结束
过滤器:使用过滤器拦截这一类资源的请求,进行统一判断是否登录,登录了允许继续访问,否则return结束。节省了每个资源都不需要判断了。
小结
-
过滤器的作用?
拦截请求与响应
-
过滤器是解决什么问题的?
解决如果每一个操作是每个资源都要操作的,那么可以将这个操作放入过滤器中集中处理
-
过滤器的应用场景
统一解决post中文乱码
统一解决登录权限控制
03.开发方式1-手动XML配置【理解】
目标
理解手动xml配置实现过滤器
实现步骤
1、创建Demo1Servlet资源,输出“执行了Demo1Servlet”
2、创建过滤器类实现Filter接口,重写拦截请求与响应的doFilter方法
3、在web.xml中配置过滤器类要拦截的资源路径
Servlet代码
package _01_创建web资源;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author 黑马程序员
*/
@WebServlet(name = "Demo1Servlet", urlPatterns = "/Demo1Servlet")
public class Demo1Servlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("执行了Demo1Servlet");
}
}
过滤器代码
package _02_手动xml创建过滤器;
import javax.servlet.*;
import java.io.IOException;
/**
* @author 黑马程序员
*/
public class Demo1Filter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
//拦截请求与响应的方法
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
//1、拦截请求
System.out.println("==执行了Demo1Filter的拦截请求的任务代码==");
//2.放行(放行就是允许去访问目标资源,如果不放行就不会去目标资源)
filterChain.doFilter(request,response);//本质:调用目标资源去执行
//注意:有这句代码就是放行,否则不放行
//3.拦截响应
System.out.println("==执行了Demo1Filter的拦截响应的任务代码==");
}
@Override
public void destroy() {
}
}
web.xml代码
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!--在web.xml中配置过滤器类要拦截的资源路径
1、定义过滤器,配置过滤器类全名
2、配置过滤器拦截的资源路径
-->
<!--定义过滤器,配置过滤器类全名-->
<filter>
<filter-name>Demo1Filter</filter-name>
<filter-class>_02_手动xml创建过滤器.Demo1Filter</filter-class>
</filter>
<!--配置过滤器拦截的资源路径-->
<filter-mapping>
<filter-name>Demo1Filter</filter-name>
<url-pattern>/Demo1Servlet</url-pattern>
</filter-mapping>
</web-app>
访问地址
http://localhost:8080/day15_01_filter_war_exploded/Demo1Servlet
效果
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tOdBA51D-1606226675662)(assets/image-20200508100412266.png)]
小结
-
实现过滤器的接口是什么?
javax.servlet.Filter
-
过滤器拦截请求与响应的方法是什么?
doFilter
04.开发方式2-注解实现【应用】
目标
使用模板向导和注解配置路径实现过滤器
实现步骤
1、创建Demo2Servlet资源,输出“执行了Demo2Servlet”
2、使用过滤器模板向导创建过滤器类,重写拦截请求与响应的doFilter方法
3、配置过滤器类的注解实现拦截路径配置
Servlet资源代码
package _01_创建web资源;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author 黑马程序员
*/
@WebServlet(name = "Demo2Servlet", urlPatterns = "/Demo2Servlet")
public class Demo2Servlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("执行了Demo2Servlet");
}
}
过滤器代码
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jVDpSVS5-1606226675666)(assets/image-20200508102127549.png)]
package _03_注解方式创建过滤器;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
/**
* @author 黑马程序员
*
* @WebFilter 过滤器注解类
* filterName = "Demo2Filter",设置过滤器别名,功能与xml<filter-name>一样, 可有可无的属性
* urlPatterns = "/Demo2Servlet", 设置拦截的资源路径,如果拦截多个路径使用数组, 这个属性必须有
*
* 注解简写方式:@WebFilter("/Demo2Servlet") 只需要配置拦截路径即可
*/
@WebFilter(filterName = "Demo2Filter",urlPatterns = "/Demo2Servlet")
public class Demo2Filter implements Filter {
public void destroy() {
}
//拦截请求与响应的方法
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
//1、拦截请求
System.out.println("==执行了Demo2Filter的拦截请求的任务代码==");
//2.放行
chain.doFilter(request,response);
//3.拦截响应
System.out.println("==执行了Demo2Filter的拦截响应的任务代码==");
}
public void init(FilterConfig config) throws ServletException {
}
}
运行效果
方法地址
http://localhost:8080/day15_01_filter_war_exploded/Demo2Servlet
效果
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-C2ltZPk2-1606226675667)(assets/image-20200508102712129.png)]
小结
-
注解实现代码是什么?
@WebFilter(filename="过滤器",urlPatterns={"/资源路径",“/xxx”})
注意:这里配置的资源路径与Servlet资源路径保存一致,必须以“/”开头
-
注解配置与xml配置出现冲突的时候,谁的优先级高?
xml的优先级高
05.过滤器执行流程【理解】
执行流程(时序图)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QIspu0Ty-1606226675669)(assets/1566385548791.png)]
注意:1、先走过滤器拦截请求
2、只有放行才可以去目标资源
3、拦截响应什么都不做就会响应给浏览器数
06.过滤器生命周期【理解】
目标
1.过滤器对象什么时候被创建?
2.服务创建过滤器对象创建了几次?
3.什么时候销毁过滤器?
实现步骤
1. 创建Demo3Servlet资源
2. 创建LifeCycleFilter拦截请求与响应,重写3个方法(init方法, doFilter方法, destroy方法)
3. 观察运行
Demo3Servlet资源代码
package _01_创建web资源;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author 黑马程序员
*/
@WebServlet(name = "Demo3Servlet", urlPatterns = "/Demo3Servlet")
public