JavaWeb中的组件Filter过滤器解析
作者:Carson's blog
过滤器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>
到此这篇关于JavaWeb中的组件Filter过滤器解析的文章就介绍到这了,更多相关JavaWeb的Filter过滤器内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!