宁波实习day13
拦截器(Filter)#
过滤器JavaWeb三大组件之一,它与Servlet很相似!不它过滤器是用来拦截请求的,而不是处理请求的
当用户请求某个Servlet时,会先执行部署在这个请求上的Filter,如果Filter“放行”,那么会继承执行用户请求的Servlet;如果Filter不“放行”,那么就不会执行用户请求的Servlet。
其实可以这样理解,当用户请求某个Servlet时,Tomcat会去执行注册在这个请求上的Filter,然后是否“放行”由Filter来决定。可以理解为,Filter来决定是否调用Servlet!当执行完成Servlet的代码后,还会执行Filter后面的代码
所谓的放行就是使用:
chain.doFilter(request, response);
chain是javax.servlet.FilterChain的参数
javaWeb中完成编写拦截器:
写过滤器就是写一个类,实现Filter(javax.servlet.Filter)接口
注册,是在web.xml中配置来完成注册!(可以使用注解的方式,在后面的笔记中我再记录)
在web.xml文件注册形式为 :
复制代码
取个名字
类的全路径名
使用上边的名字
要拦截的范围(可以使/*,表示拦截所有请求,还可以是拦截某个Servlet)
复制代码
和Servlet在web.xml中的配置很相似吧
注意:Filter在web.xml中配置是有顺序的,先配置的先拦截
还有一个值得注意的地方是:不要认为一个请求在给浏览器输出就完成了,实际上很多事情都需要在给客户端响应之后才能完成,可以在放行语句的前后各输出一句话,可以看到,在Filter放行之后,浏览器就可以输出一个页面(如果Servlet中不做过多操作,只起一个转跳的作用),但是放行之后的语句还是会在控制台输出
过滤器的生命周期#
Filter的生命周期(和Servlet的生命周期类似)
init(FilterConfig):在服务器启动时会创建Filter实例,并且每个类型的Filter只创建一个实例,从此不再创建!在创建完Filter实例后,会马上调用init()方法完成初始化工作,这个方法只会被执行一次;
doFilter(ServletRequest req,ServletResponse res,FilterChain chain):这个方法会在用户每次访问“目标资源(pattern>index.jsp)”时执行,如果需要“放行”,那么需要调用FilterChain的doFilter(ServletRequest,ServletResponse)方法,如果不调用FilterChain的doFilter()方法,那么目标资源将无法执行;
destroy():服务器会在创建Filter对象之后,把Filter放到缓存中一直使用,通常不会销毁它。一般会在服务器关闭时销毁Filter对象,在销毁Filter对象之前,服务器会调用Filter对象的destory()方法
四种拦截方式#
我们来做个测试,写一个过滤器,指定过滤的资源为b.jsp,然后我们在浏览器中直接访问b.jsp,你会发现过滤器执行了!
但是,当我们在a.jsp中request.getRequestDispathcer(“/b.jsp”).forward(request,response)时,就不会再执行过滤器了!也就是说,默认情况下,只能直接访问目标资源才会执行过滤器,而forward执行目标资源,不会执行过滤器
其实过滤器有四种拦截方式!分别是:REQUEST、FORWARD、INCLUDE、ERROR。
REQUEST:直接访问目标资源时执行过滤器。包括:在地址栏中直接访问、表单提交、超链接、重定向,只要在地址栏中可以看到目标资源的路径,就是REQUEST;
FORWARD:转发访问执行过滤器。包括RequestDispatcher#forward()方法、jsp:forward标签都是转发访问;
INCLUDE:包含访问执行过滤器。包括RequestDispatcher#include()方法、jsp:include标签都是包含访问;
ERROR:当目标资源在web.xml中配置为中时,并且真的出现了异常,转发到目标资源时,会执行过滤器
可以在中添加0~n个子元素,来说明当前访问的拦截方式:
复制代码
myfilter
/b.jsp
REQUEST
FORWARD
复制代码
当没有给出拦截方式时,那么默认为REQUEST,其实最为常用的就是REQUEST和FORWARD两种拦截方式,而INCLUDE和ERROR都比较少用
我们可以使用拦截器实现一个错误转跳的功能,但发生错误就转跳到一个错误页面:
复制代码
myfilter
/b.jsp
ERROR
500
/b.jsp
复制代码
我们就可以在b.jsp中编写一个错误提示页面,或者是做一些其他操作
过滤器的应用场景#
执行目标资源之前做预处理工作,例如设置编码,这种处理通常都会放行,只是在目标资源执行之前做一些准备工作
通过条件判断是否放行,例如校验当前用户是否已经登录,或者用户IP是否已经被禁用;
进行权限控制
最后我们再来看看Filter在SSH整合中的使用:
当然是Struts2的使用啦:
复制代码
struts2
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
struts2
/*
复制代码
StrutPrepareAndExecuteFilter这个拦截器的作用就是拦截所有请求