🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
[TOC] # Filter的API详解 创建一个类implements Filter ## Filter生命周期及其与生命周期 Filter接口有三个方法,并且这个三个都是与Filter的生命相关的方法 * init(Filterconfig):代表filter对象初始化方法 filter对象创建时执行 * doFilter(ServletRequest,ServletResponse,FilterChain):代表filter执行过滤的核心方法,如果某资源在已经被配置到这个filter进行过滤的话,那么每次访问这个资源都会执行doFilter方法 * destory():代表是filter销毁方法 当filter对象销毁时执行该方法 Filter对象的生命周期: * Filter何时创建:服务器启动时就创建该filter对象 * Filter何时销毁:服务器关闭时filter销毁 ## Filter的API详解 ### init(FilterConfig) 其中参数config代表 该Filter对象的配置信息的对象,内部封装是该filter的配置信息 ~~~ @Override public void init(FilterConfig filterConfig) throws ServletException { System.out.println("FirstFilter中的init---"); String filterName = filterConfig.getFilterName(); System.out.println(filterName); ServletContext servletContext = filterConfig.getServletContext(); String initParameter = filterConfig.getInitParameter("charset"); System.out.println(initParameter); } ~~~ #### FilterConfig接口 用户在配置filter时,可以使用`<init-param>`为filter配置一些初始化参数,当web容器实例化Filter对象,调用其init方法时,会把封装了filter初始化参数的filterConfig对象传递进来。因此开发人员在编写filter时,通过filterConfig对象的方法,就可获得: * String getFilterName():得到filter的名称。 * String getInitParameter(String name): 返回在部署描述中指定名称的初始化参数的值。如果不存在返回null。 * Enumeration getInitParameterNames():返回过滤器的所有初始化参数的名字的枚举集合。 * public ServletContext getServletContext():返回Servlet上下文对象的引用 ### destory()方法 filter对象销毁时执行 ### doFilter方法 `doFilter(ServletRequest,ServletResponse,FilterChain)` 其中的参数: ServletRequest/ServletResponse:每次在执行doFilter方法时 web容器负责创建一个request和一个response对象作为doFilter的参数传递进来。该request个该response就是在访问目标资源的service方法时的request和response。 **FilterChain:过滤器链对象,通过该对象的doFilter方法可以放行该请求** ~~~ @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { //过滤请求方法 System.out.println("请求到达FirstFilter---"); //如果满足条件就放行(不放行请求就被拦截了) filterChain.doFilter(servletRequest, servletResponse); System.out.println("请求回到FirstFilter---"); } ~~~ 里面的ServletRequest可以强转为HttpServletRequest # Filter的配置 注解方式 ~~~ @WebFilter("/*") ~~~ 在web.xml中配置的过滤器的先后顺序是依`<filter-mapping>`的顺序而定,形成一个链条 ~~~ <filter> <filter-name>firstFilter</filter-name> <filter-class>com.jdxia.Filter.FirstFilter</filter-class> <init-param> <param-name>charset</param-name> <param-value>UTF-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>firstFilter</filter-name> <!-- 这边的url-pattern写成servlet-name也可以 --> <!-- url可以写成/* --> <url-pattern>/MyServlet</url-pattern> </filter-mapping> <filter> <filter-name>secondFilter</filter-name> <filter-class>com.jdxia.Filter.SecondFilter</filter-class> </filter> <filter-mapping> <filter-name>secondFilter</filter-name> <url-pattern>/MyServlet</url-pattern> <dispatcher>REQUEST</dispatcher> </filter-mapping> ~~~ url-pattern配置时 1. 完全匹配 /sertvle1 2. 目录匹配 `/aaa/bbb/* `----最多的 `/user/*`:访问前台的资源进入此过滤器 `/admin/*`:访问后台的资源时执行此过滤器 3. 扩展名匹配` *.abc *.jsp` 注意:url-pattern可以使用servlet-name替代,也可以混用 `/*.jsp`是错误的 **注意:一个`<filter>`可以对应多个`<filter-mapping>`** # dispatcher:访问的方式 ~~~ @WebFilter(value = "/*", dispatcherTypes = DispatcherType.REQUEST) public class FilterDemo1 implements Filter { ~~~ 可以设置多个`<dispatcher>`子元素用来指定 Filter 对资源的多种调用方式进行拦截 * REQUEST:默认值,代表直接访问某个资源时执行filter * FORWARD:转发时才执行filter,是通过 RequestDispatcher 的 forward() 方法访问时 * INCLUDE: 包含资源时执行filter,通过 RequestDispatcher 的 include() 方法访问时 * ERROR:发生错误时 进行跳转才执行filter,通过声明式异常处理机制调用时 # Filter的作用 1. 公共代码的提取 2. 可以对request和response中的方法进行增强(装饰者模式/动态代理) 3. 进行权限控制 # 生命周期 对象从创建到销毁过程 filter对象只会创建一次,init方法也只会执行一次 * 构造器: 服务器启动立即调用构造器创建Filter对象 * init(): Filter对象创建成功立即调用(完成初始化操作) * doFilter(): 每次请求过滤资源时都会调用 * destroy(): 关闭服务器时调用销毁filter对象 # 过滤器链 1. 注解配置: 按照类名的字符串比较规则比较,值小的先执行 2. web.xml配置: `filter-mapping`谁定义在上面,谁先执行