Java登陆第三十一天——Filter
Filter即过滤器,专用于控制访问资源。
人话:过滤客户端的请求。
生活中的过滤器
-
筛子
-
地铁闸门
-
公司前台
-
保安
以上举例都是生活中的过滤器。
在代码中,过滤器的作用是控制访问资源。
Filter
所有的过滤器都要实现Filter接口,Filter接口方法如下:
方法名 | 描述 |
---|---|
default void init(FilterConfig filterConfig) | 过滤器初始化(可不实现) |
void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) | 过滤器真正工作的方法 |
default void destroy() | 过滤器销毁(可不实现) |
过滤器也是有生命周期的,同样也是由Tomcat创建。
接口实现类可以不实现默认方法。
FilterChain类是过滤器链,因为过滤器可以有多个。
FilterChain过滤器链
FilterChain接口方法如下:
方法名 | 描述 |
---|---|
void doFilter(ServletRequest var1, ServletResponse var2) | 把请求与响应对象传递给服务端 |
如果把FilterChain当作保安的话,其doFilter方法就是放行,允许通过。
注意!!!
Filter的doFilter()方法是实现过滤器的具体逻辑的方法
FilterChain的doFilter()方法是放行请求与响应的方法。
Filter生效位置
在web.xml中配置过滤器映射
<filter>
<filter-name>过滤器名称</filter-name>
<filter-class>过滤器的全类名</filter-class>
</filter>
<!--过滤器映射-->
<filter-mapping>
<filter-name>过滤器名称</filter-name>
<url-pattern>过滤器作用的URL1</url-pattern>
<url-pattern>过滤器作用的URL2</url-pattern>
</filter-mapping>
-
一个过滤器映射可以配置多个url-pattern
-
可以使用通配符/和*
-
如果有多个过滤器映射,根据web.xml中,过滤器映射顺序确定过滤器的执行顺序
过滤器栗子
TestFilter7
public class TestFilter7 implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
servletRequest.setAttribute("temp","过滤器可以修改请求与响应");
//放行==传递请求和响应给服务端
filterChain.doFilter(servletRequest, servletResponse);
}
}
TestServlet7
@WebServlet("/Test7")
public class TestServlet7 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//验证是否还是同一个请求对象
System.out.println(req.getAttribute("temp"));
}
}
web.xml
<filter>
<filter-name>T7</filter-name>
<filter-class>com.example.JavaWeb.Filter.TestFilter7</filter-class>
</filter>
<filter-mapping>
<filter-name>T7</filter-name>
<url-pattern>/Test7</url-pattern>
</filter-mapping>
客户端请求URL:http://localhost:8080/JavaWeb_war_exploded/Test7
//控制台输出
过滤器可以修改请求与响应
不放行的栗子
修改上述栗子的TestFilter7,注释掉放行代码
public class TestFilter7 implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
servletRequest.setAttribute("temp","过滤器可以修改请求与响应");
//放行==传递请求和响应给服务端
//filterChain.doFilter(servletRequest, servletResponse);
}
}
客户端请求URL:http://localhost:8080/JavaWeb_war_exploded/Test7
//控制台没有输出
因为请求到达不了TestServlet7处,所以压根没有输出。
多个过滤器
一个项目中,可以同时存在多个过滤器。多个过滤器也可以对同一个资源进行过滤。
过滤器执行顺序由web.xml中的过滤器映射顺序决定。
注解配置Filter
使用@WebFilter("URL")注解
栗子
@WebFilter("/Test7")
public class TestFilter7 implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
servletRequest.setAttribute("temp","过滤器可以修改请求与响应");
//放行==传递请求和响应给服务端
filterChain.doFilter(servletRequest, servletResponse);
}
}
注解如何确定过滤器执行顺序
接口实现类的类名,没错,就是这么简单粗暴。但是Java不允许使用数字作为类名
推荐用以下类名
F数字_XXXFilter
例如:
F1_wordFilter (用于过滤敏感字符)
请求转发和响应重定向过滤器问题
经测试
请求转发只会经过一次过滤器。(因为本身还是原来的请求)
重定向会经过两次过滤器。(产生了两次请求)