过滤器Filter
过滤器Filter的概念
Filter:是一个实现了特殊接口(Filter)的Java类。
- 实现对请求资源(jsp,servlet,html)的过滤的功能。
- 过滤器是一个运行在服务器的程序, 优先于请求资源(Servlet或者jsp,html)之前执行。
- 过滤器是javaweb技术中最为实用的技术之一。
过滤器Filter的作用
Filter: 过滤网站的数据,对目标资源(Servlet,jsp)进行过滤。
过滤器常见应用:
- 处理中文乱码
- 登陆验证
- 权限拦截
- 过滤敏感字符
- …
Filter作用图示如下:
过滤器Filter的生命周期
生命周期阶段 | 执行时机 | 生命周期方法 |
---|---|---|
创建对象 | Web应用启动时 | init方法,通常在该方法中做初始化工作,只执行一次 |
拦截请求 | 接收到匹配的请求 | doFilter方法,通常在该方法中执行拦截过滤,此方法执行多次 |
销毁 | Web应用卸载前 | destroy方法,通常在该方法中执行资源释放,只执行一次 |
过滤器Filter的匹配规则
过滤器匹配的目的是指定当前过滤器要拦截哪些资源。
精确匹配
指定被拦截资源的完整路径:
<!-- 配置Filter要拦截的目标资源 -->
<filter-mapping>
<!-- 指定这个mapping对应的Filter名称 -->
<filter-name>FilterDemo01</filter-name>
<!-- 通过请求地址模式来设置要拦截的资源 -->
<url-pattern>/servletDemo01</url-pattern>
</filter-mapping>
上述例子表示要拦截映射路径为/servletDemo01
的这个资源
模糊匹配
相比较精确匹配,使用模糊匹配可以让我们创建一个Filter就能够覆盖很多目标资源,不必专门为每一个目标资源都创建Filter,提高开发效率。
比如我们配置了url-pattern为/user/*
之后,请求地址只要是/user开头的那么就会被匹配。
<filter-mapping>
<filter-name>Target02Filter</filter-name>
<!-- 模糊匹配:前杠后星 -->
<!--
/user/demo01
/user/demo02
/user/demo03
/demo04
-->
<url-pattern>/user/*</url-pattern>
</filter-mapping>
极端情况:/* 匹配所有请求
扩展名匹配
<filter>
<filter-name>Target04Filter</filter-name>
<filter-class>com.carson.filter.Target04Filter</filter-class>
</filter>
<filter-mapping>
<filter-name>Target04Filter</filter-name>
<url-pattern>*.png</url-pattern>
</filter-mapping>
上述例子表示拦截所有以.png
结尾的请求。
Servlet名称匹配
<filter-mapping>
<filter-name>Target05Filter</filter-name>
<!-- 根据Servlet名称匹配 -->
<servlet-name>Target01Servlet</servlet-name>
</filter-mapping>
过滤器链
过滤器链的概念
一个请求可能被多个过滤器所过滤,只有当所有过滤器都放行,请求才能到达目标资源,如果有某一个过滤器没有放行,那么请求则无法到达后续过滤器以及目标资源,多个过滤器组成的链路就是过滤器链。
过滤器链的顺序
过滤器链中每一个Filter执行的顺序是由web.xml中filter-mapping配置的顺序决定的
。如果某个Filter是使用ServletName进行匹配规则的配置,那么这个Filter执行的优先级要更低。
过滤器链的案例
创建ServletDemo01
ServletDemo01.java
public class ServletDemo01 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("ServletDemo01接收到了请求...");
}
}
web.xml:
<servlet>
<servlet-name>servletDemo01</servlet-name>
<servlet-class>com.carson.ServletDemo01</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>servletDemo01</servlet-name>
<url-pattern>/ServletDemo01</url-pattern>
</servlet-mapping>
<!--创建多个Filter拦截Servlet:-->
<filter-mapping>
<filter-name>TargetChain03Filter</filter-name>
<url-pattern>/ServletDemo01</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>TargetChain02Filter</filter-name>
<url-pattern>/ServletDemo01</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>TargetChain01Filter</filter-name>
<url-pattern>/ServletDemo01</url-pattern>
</filter-mapping>
过滤器Filter应用示例
Filter开发步骤:
- 导包(maven项目的pom.xml)
<dependencies>
<!--JSP依赖-->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.3</version>
</dependency>
<!--Servlet依赖-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
</dependency>
<!--JSTL表达式的依赖-->
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>jstl-api</artifactId>
<version>1.2</version>
</dependency>
<!--standard标签库-->
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
<!--链接数据库-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.19</version>
</dependency>
</dependencies>
- 编写过滤器(以处理乱码问题的过滤器为例)
- 编写的类继承的接口不要错(选择javax.servlet的Filter接口)
- 实现Filter接口,重写对应的方法即可。
package com.carson.filter;
import javax.servlet.*;
import java.io.IOException;
public class CharacterEncodingFilter implements Filter {
//初始化:当web服务器启动时,就自动初始化了,随时等待过滤对象的出现
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("CharacterEncodingFilter已经初始化");
}
/*
1:过滤器中的所有代码,在过滤特定请求的时候都会执行
2:必须写chain.foFilter()方法让过滤器继续前进
*/
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//转换request和response为HttpServlet类型
HttpServletRequest request = (HttpServletRequest) request;
HttpServletResponse response = (HttpServletResponse) response;
解决请求参数的中文乱码问题
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=UTF-8");
System.out.println("CharacterEncodingFilter执行前");
//让我们的请求继续走,如果不写,程序到这里就会被拦截停止
//即这句代码表示放行
filterChain.doFilter(servletRequest,servletResponse);
System.out.println("CharacterEncodingFilter执行后");
}
//销毁:当web服务器关闭的时候,会进行销毁
public void destroy() {
System.out.println("CharacterEncodingFilter已经销毁");
}
}
- 在web.xml中配置Filter(设置过滤的路径)
<!--注册filter过滤器,类似注册servlet-->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>com.carson.filter.CharacterEncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<!--filter的路径配置:只要是/servlet的任何请求,都会经过这个过滤器-->
<!--即设置过滤器的过滤请求路径-->
<url-pattern>/servlet/*</url-pattern>
</filter-mapping>
The End!!创作不易,欢迎点赞/评论!!欢迎关注个人公众号