最最基础的Filter信息:
- Filter对象是在Web应用启动时被创建和初始化的(嗯,服务器启动时),在停止时被销毁
- Filter是单例多线程的(与Servlet类似),为了保护其安全性,就别在内部添加可修改的成变了。
- Filter中的chain对象(链)的doFilter()方法与Filter的doFilter()方法不要混淆。
- chain的doFilter()方法是放行请求到下一个资源的重要方法。
Filter的注册方式与Servlet类似,
但是!<url-pattern/>中的参数含义不同
- Servlet的<url-pattern/>:访问该Servlet的路径
- Filter的<url-pattern/>:拦截请求URI的适配路径(我不知道专业的名词!)
- Filter的<url-pattern/>中的参数不能是“ / ”!具体原因是:如果写成“ / ”,就无法拦截动态资源了。
- Filter的<url-pattern/>可以由<servlet-name>代替,指代Filter对指定Servlet的请求进行拦截
- Filter也可以设置<init-param>;通过FilterConfig获取其信息
Filter的<filter-mapping>中还有一个<dispatcher/>标签
其中有四个参数:这四个参数主要对应请求转发request.getRequestDispatcher("/?").????
- FORWARD 使Filter只拦截以forward方式进行请求转发的请求(。。。。好像写麻烦了)
- INCLUDE 使Filter只拦截以include方式进行请求转发的请求
- RESPECT 默认值!(我的理解就是:会拦截一切符合<url-pattern/>的请求)
-
ERROR 请求跳转到错误页面时,会被拦截
Filter是可以修改请求与响应的
当应用中存在多个Filter时,其执行顺序与其注册顺序一致。
老师说的面试重点:Servlet 和 Filter 的执行原理:
Servlet:
Web容器中存在两个Map,
这两个Map的key均为Servlet注册时的<url-pattern/>值,但其value是不同的,
第一个Map的value是Servlet实例对象的引用
第二个Map的value为<servlet-name/>的值,即Servlet类的全限定性类名。
执行原理:
当对Servlet的请求到达Web容器时,会先对请求进行解析,
使用解析出的URI作为比较对象,从第一个Map中查找是否有匹配的key。
若存在匹配的key,那么读取其value(Servlet对象的引用),执行Servlet的service()方法。不再向后查找。
若不存在匹配的key,再从第二个Map中查找是否有匹配的key,若存在则读取其value,即要访问的Servlet的全限
定性类名。
然后使用反射机制创建该Servlet实例。并将该实例写入到第一个Map中,然后再执行该Servlet的service()方法。
Class.forName(className).instance();若第二个Map中也没有找到匹配的key,那么跳转到系统错误处理页面404。(这鬼畜的换行,我是真的难受!)
Filter:
一个数组与一个Map
一个Map:Key为<url-pattern/>的值,value为Filter实例对象的引用
一个数组:存放这与请求向匹配的所有Filter
执行原理:
当对某资源的请求到达Web容器时,会先对请求进行解析,使用解析出的URI作为比较对象,从Map中查找是否存在
相匹配的key。
若存在,那么读取其Value,即Filter对象的引用,将其引用存入到数组中。然后继续向后查找,直到将Map查找完
毕。
这样在数组中就会存在按照查找顺序排序的Filter引用。数组初始化完毕后,开始按照数组元素顺序进行执行,所有数组中的Filter全部执行完毕后,再跳转到请求的目标资
源。
学习课程为:动力节点 Reyco Filter 01~11
刚刚开始写,每天都写一点,主要自用排版很差,见谅!
stay hungary stay foolish!
2018-5-9
RockAnts