javaweb中的过滤器.docx
- 文档编号:5862729
- 上传时间:2023-01-01
- 格式:DOCX
- 页数:33
- 大小:74.85KB
javaweb中的过滤器.docx
《javaweb中的过滤器.docx》由会员分享,可在线阅读,更多相关《javaweb中的过滤器.docx(33页珍藏版)》请在冰豆网上搜索。
javaweb中的过滤器
day15
过滤器(Filter)
过滤器概述
i什么是过滤器
过滤器JavaWeb三大组件之一,它与Servlet很相似!
不它过滤器是用来拦截请求的,而不是处理请求的。
当用户请求某个Servlet时,会先执行部署在这个请求上的Filter,如果Filter“放行”,那么会继
承执行用户请求的Servlet;如果Filter不"放行”,那么就不会执行用户请求的Servlet。
其实可以这样理解,当用户请求某个Servlet时,Tomcat会去执行注册在这个请求上的Filter,
然后是否“放行”由Filter来决定。
可以理解为,Filter来决定是否调用Servlet!
当执行完成Servlet
的代码后,还会执行Filter后面的代码。
过滤器Servlet
程序输出;
start.*.
servlet
end...
2过滤器之helloworld
其实过滤器与Servlet很相似,我们回忆一下如果写的第一个Servlet应用!
写一个类,实现Servlet
接口!
没错,写过滤器就是写一个类,实现Filter接口。
publicclassHelloFilterimplementsFilter{
publicvoidinit(FilterConfigfilterConfig)throwsServletException{}
publicvoiddoFilter(ServletRequestrequest,ServletResponseresponse,
FilterChainchain)throwslOException,ServletException{
System.out.println("HelloFilter");
}
publicvoiddestroy。
{}
}
第二步也与Servlet一样,在web.xml文件中部署Filter:
vfilter>
vfilter-name >helloFilter >cn.itcast.filt er.HelloFilter >
>
vfilter-mapping
>
>helloFilter
>
vurl-pattern
>/index.jsp
>
>
应该没有问题吧,都可以看懂吧!
OK了,现在可以尝试去访问index.jsp页面了,看看是什么效果!
当用户访问index.jsp页面时,会执行HelloFilter的doFilter()方法!
在我们的示例中,index.jsp
页面是不会被执行的,如果想执行index.jsp页面,那么我们需要放行!
有很多同学总是错误的认为,一个请求在给客户端输出之后就算是结束了,这是不对的!
其实很多事情都需要在给客户端响应之后才能完成!
过滤器详细
1过滤器的生命周期
我们已经学习过Servlet的生命周期,那么Filter的生命周期也就没有什么难度了!
init(FilterConfig):
在服务器启动时会创建Filter实例,并且每个类型的Filter只创建一个实
例,从此不再创建!
在创建完Filter实例后,会马上调用init()方法完成初始化工作,这个
方法只会被执行一次;
doFilter(ServletRequestreq,ServletResponseres,FilterChainchain):
这个方法会在用户每次访问“目标资源(
的doFilter()方法,那么目标资源将无法执行;
destroy():
服务器会在创建Filter对象之后,把Filter放到缓存中一直使用,通常不会销毁
它。
一般会在服务器关闭时销毁Filter对象,在销毁Filter对象之前,服务器会调用Filter
对象的destory()方法。
2FilterConfig
你已经看到了吧,Filter接口中的init()方法的参数类型为FilterConfig类型。
它的功能与
ServletConfig相似,与web.xml文件中的配置信息对应。
下面是FilterConfig的功能介绍:
ServletContextgetServletContext():
获取ServletContext的方法;
StringgetFilterName():
获取Filter的配置名称;与 StringgetInitParameter(Stringname): 获取Filter的初始化配置,与 EnumerationgetlnitParameterNames(): 获取所有初始化参数的名称。 puJilicclassHel丄oFil匕合応戈mpltaii合ntwFilter{ puJtlicvoidinlt(FllterConfigfilterConfig)throwsSeirvletExcepElon{ StringfjlttzXcinw*=fllterConfig・gut: FjLLt^i: IilSLmr(]; Strj.111=filterConf±g・getIn±七cuneter(^pariuiiHam.c1ff}; 口nameiSsfilterCo口丘ig・号暑七InLtParamsterN^iuEs(); txprxn七丄]i[filtExNameyi System・puf・pcxnt丄口[valj;while(names+hssNoreELements(I){ String口削熄=(String)namesnextElentent(); Ftr.mg卩目丄口启=flltgrConfigPg@tInitPaiTRrnetei: (n&ni台);守¥日七己尬・outBprlntln(name+"*="+valueJ; 3FilterChain doFilter()方法的参数中有一个类型为FilterChain的参数,它只有一个方法: doFilter(ServletRequest,ServletResponse)。 前面我们说doFilter()方法的放行,让请求流访问目标资源! 但这么说不严密,其实调用该方法 的意思是,“我(当前Filter)”放行了,但不代表其他人(其他过滤器)也放行。 也就是说,一个目标资源上,可能部署了多个过滤器,就好比在你去北京的路上有多个打劫的匪人(过滤器),而其中第一伙匪人放行了,但不代表第二伙匪人也放行了,所以调用FilterChain类 的doFilter()方法表示的是执行下一个过滤器的doFilter()方法,或者是执行目标资源! 如果当前过滤器是最后一个过滤器,那么调用chain.doFilter()方法表示执行目标资源,而不是 最后一个过滤器,那么chain.doFilter()表示执行下一个过滤器的doFilter()方法。 4多个过滤器执行顺序 一个目标资源可以指定多个过滤器,过滤器的执行顺序是在web.xml文件中的部署顺序: vfilter> vfilter-namevfilter-class >myFilter1 >cn.itcast.fi
lter.MyFilter1
>
>
vfilter-mapping
>
>myFilter1
>
>/index.jsp
>
vfilter-name
vfilter-class
>myFilter2
>cn.itcast.filter.MyFilter2
vfilter-mapping
vfilter-name
>myFilter2 >/index.jsp
publicclassMyFilter1extendsHttpFilter{
publicvoiddoFilter(HttpServletRequestrequest,HttpServletResponse
response.
FilterChainchain)
System.out.println(
throwslOException,ServletException{
"filterlstart..."
chain.doFilter(request,response);
System.out.println("filter1end..."
);
//放行,执行MyFilter2的doFilter()
);
方法
}
publicclassMyFilter2extendsHttpFilter{
publicvoiddoFilter(HttpServletRequestrequest,HttpServletResponse
response,
FilterChainchain)
System.out.println(
throwsIOException,ServletException{
"filter2start..."
chain.doFilter(request,response);
System.out.println("filter2end..."
);
//放行,执行目标资源
);
ThisismyJSPpage.
index.jsp
<%System.out.println(
"index.jsp"
);%>
当有用户访问index.jsp页面时,输出结果如下:
filter1start...
filter2start...
index.jspfilter2end...
filter1end...
5四种拦截方式
我们来做个测试,写一个过滤器,指定过滤的资源为b.jsp,然后我们在浏览器中直接访问b.jsp,
你会发现过滤器执行了!
但是,当我们在a.jsp中request.getRequestDispathcer(“/b.jsp”).forward(request,resp时se就
不会再执行过滤器了!
也就是说,默认情况下,只能直接访问目标资源才会执行过滤器,而forward
执行目标资源,不会执行过滤器!
publicclassMyFilterextendsHttpFilter{
publicvoiddoFilter(HttpServletRequestrequest,
HttpServletResponseresponse,FilterChainchain)throwsIOException,ServletException{
System.out.println("myfilter...");
chain.doFilter(request,response);
}
}
>
>myfilter >cn.itcai st.filter.MyFilter > >myfilter >/b.jsp >
b.jsp
a.jsp
<%
request.getRequestDispatcher("/b.jsp").forward(request,response);
%>