资源描述
Click to edit,Click to edit Master text styles,Second level,Third level,Fourth level,Fifth level,第,13,讲,Servlet,过滤器,什么是过滤器,Filter API,过滤器的部署,过滤器的使用,1.,什么是过滤器,(,filter),(1),日常生活中的“过滤”例子,自饮水的“过滤”、信息“过滤”、香烟的“过滤嘴”、用筛子,筛选沙子等,Java,Servlet,2.3,起增加了过滤器的功能,,2.4,、,2.5,进一步增强、完善,(2),什么是过滤器,顾名思义,,就是在源数据和目的数据之间起过滤作用的中间组件,客户端,目标资源,(,可以是,servlet,、,jsp,、,html,文件,),过滤器,请求,请求,响应,响应,概念:,过滤器,是一种特殊的,Servlet,,它可以用来对,Servlet容器的请求和响应对象进行检查和修改,,,提供过滤作用。,Servlet过滤器本身并不生成请求和响应对象,,但,可以对它们进行,过滤,,,即:,在Servlet被调用,之前,检查Request对象,修改Request,Header和Request内容,;,在Servlet被调用,之后,检查Response对象,修改Response,Header和Response内容,。,Servlet过滤器负责过滤的Web组件可以是,Servlet、JSP或HTML文件,。,多个过滤器串联在一起可形成,过滤器链,(Filter Chain,),客户端,目标资源,(,可以是,servlet,、,jsp,、,html,文件,),过滤器,1,请求,请求,响应,响应,过滤器,2,请求,响应,过滤器,3,请求,响应,(3),过滤器用途,对用户请求进行统一认证,(,如:限制,IP,、不允许黑名单用户访问,),对用户请求进行记录、审核,(,如:写入日志等,),对用户发送的数据进行过滤或替换,(,如:过滤不良信息等,),转换图像格式,对响应内容进行压缩,减少传输量,对请求、响应内容进行加密、解密操作,2.Filter API,过滤器本质上是一个,Servlet,类,只是它要实现,Filter,接口。,与过滤器有关的接口有三个,,分别是:,Filter,、,FilterConfig,、,FilterChain,,位于,javax.servlet,包中。,Filter,接口,既然过滤器是一个,Servlet,,学习时就,可以把过滤器与,servlet,进行类比,。一个过滤器也有自己的生命周期,包括:,初始化、处理请求和响应、销毁等阶段,,规定以下三个方法与之对应:,void,init(FilterConfig,filterConfig,),:这是,Servlet,过滤器的初始化方法,,Servlet,容器创建,Servlet,过滤器实例后将调用这个方法。在此方法中可以读取,web.xml,文件中,Servlet,过滤器的初始化参数,也可获取应用程序的上下文对象;,void doFilter(ServletRequest request,ServletResponse response,FilterChain chain),:完成实际的过滤操作。当客户请求访问与过滤器关联的,URL,时,,Servlet,容器将先调用过滤器的,doFilter,方法。,FilterChain,参数用于访问后续过滤器,public void,doFilter(ServletRequest,request,ServletResponse,response,FilterChain,chain,)throws,IOException,ServletException,/,前置代码块,在访问资源前执行,chain.doFilter(request,response);,/,后置代码块,在访问资源后执行,void destroy(),:,Servlet,容器在销毁过滤器实例前调用该方法,可在此释放,Servlet,过滤器占用的资源,/,过滤器的基本结构,import,java.io,.*;,import,javax.servlet,.*;,public class,FirstFilter,implements Filter,private,FilterConfig,filterConfig,=null;,public void,init(FilterConfig,filterConfig,)throws,ServletException,this.filterConfig,=,filterConfig,;,public void,doFilter(ServletRequest,request,ServletResponse,response,FilterChain,chain),throws,IOException,ServletException,/,前置代码块,chain.doFilter(request,response);,/,后置代码块,public void destroy(),this.filterConfig,=null;,(2)FilterChain,接口,:,只定义了一个方法,void,doFilter(ServletRequest,request,ServletResponse,response,),:,过滤器链中的下一个过滤器被调用,如果调用该方法的过滤器是最后一个过滤器,那么目标资源将被调用。,W,eb,容器,Filter1.doFilter,方法,/,前置代码块,FilterChain.doFilter,方法,/,后置代码块,Filter2.doFilter,方法,/,前置代码块,FilterChain.doFilter,方法,/,后置代码块,servlet.service,方法,1,2,3,4,5,6,(3)FilterConfig,接口,:,获取,ServletContext,和,Filter,配置参数,定义的方法有:,String,getFilterName,(),:,得到过滤器名字,ServletContext,getServletContext,(),:,得到上下文对象,String,getInitParameter(String,name),:,得到指定名称的初始参数,Enumeration,getInitParameterNames,(),:,得到所有初始参数的名称,(,类型为,Enumeration,),3.,过滤器的部署,需要在,web.xml,文件中对过滤器进行,声明、映射,过滤器名字,过滤器类名,/,可选,参数名,参数值,过滤器名字,访问路径,或,Servlet,名字,REQUEST/INCLUDE/FORWARD/ERROR,/,可选,4.,过滤器的使用,import,java.io,.*;,import,javax.servlet,.*;,public class,SimpleFilter,implements Filter,public void,init(FilterConfig,filterConfig,)throws,ServletException,public void,doFilter(ServletRequest,request,ServletResponse,response,FilterChain,chain)throws,IOException,ServletException,response.setContentType(text/html;charset,=GB2312);,PrintWriter,out=,response.getWriter,();,out.println,(before,doFilter,();,chain.doFilter(request,response);,out.println,(after,doFilter,();,public void destroy(),例,1:,最简单过滤器,(filter1,项目,),SimpleFilter,SimpleFilter,SimpleFilter,/*,index.jsp,web.xml,import,java.io,.*;,import,javax.servlet,.*;,public class,Simple,Filter2 implements Filter,public void,init(FilterConfig,filterConfig,)throws,ServletException,public void,doFilter(ServletRequest,request,ServletResponse,response,FilterChain,chain)throws,IOException,ServletException,response.setContentType(text/html;charset,=GB2312);,PrintWriter,out=,response.getWriter,();,out.println,(,在调用第二个过滤器之前,);,chain.doFilter(request,response);,out.println,(,在调用第二个过滤器之后,);,public void destroy(),例,1:,最简单过滤器,(filter1,项目,),再增加一个过滤器,SimpleFilter,SimpleFilter,SimpleFilter,/*,Simple,Filter2,Simple,Filter2,Simple,Filter2,/*,index.jsp,web.xml,import,java.io,.*;,import,java.util,.*;,import,javax.servlet,.*;,import,javax.servlet.http,.*;,public class,MyFilter,implements Filter,private,FilterConfig,filterConfig,=null;,String,paramValue,=null;,public void,init(FilterConfig,filterConfig,)throws,ServletException,this.filterConfig,=,filterConfig,;,paramValue,=,filterConfig.getInitParameter(encoding,);,public,void,doFilter(ServletRequest,request,ServletResponse,response,FilterChain,chain)throws,IOException,ServletException,/*,下面这段代码在命令行窗口中打印出所有的请求头信息,,,以便确认Filter是否起作用和帮助分析问题,*/,System.out.println(begin,headers-);,Enumeration,headerNames,=(,HttpServletRequest,)request),.,getHeaderNames,();,例,2:,过滤器,(filter2,项目,),while(,headerNames.hasMoreElements,(),String,headerName,=(String),headerNames.nextElement,();,System.out.println(headerName,+:+,(,HttpServletRequest,),request).getHeader(headerName,);,System.out.println,(-end headers);,/,在调用目标Servlet前写入响应内容,response.setContentType(text/html;charset,=gb2312);,PrintWriter,out=,response.getWriter,();,out.println(您的IP地址为,:+,request.getRemoteHost,()+);,chain.doFilter(request,response);,/,在目标Servlet返回后写入响应内容,out.println,(,filter初始化参数,:,名字,=encoding,值=+,paramValue,);,out.println,(,当前web程序的真实路径为,=,+,filterConfig.getServletContext().getRealPath,(/);,public void destroy(),this.filterConfig,=null;,MyFilter,MyFilter,encoding,GB2312,MyFilter,/*,index.jsp,web.xml,例,3:,用过滤器实现静态页面的访问保护,(filter3,项目,),在应用程序目录有一子目录,articles,,它保存有,aticle1.html,和,article2.html,,上下文根目录下的,articles.html,包含访问这两个,html,文件的超链接。,现在,要对这两个静态文档进行保护,只有用户名、密码正确才能访问。,用户名:,sise,密码:,123456,当然,不必每次访问这两个文档都要输入用户名、密码,只要输入一次即可。,解决思路:,用过滤器来保护这两个页面;,对于合法用户,要发放“通行证”,(session,设置属性,),。,/,过滤器主要代码,public void,doFilter(ServletRequest,request,ServletResponse,response,FilterChain,chain)throws,IOException,ServletException,HttpServletRequest,req,=(,HttpServletRequest,)request;,HttpSession,session=,req.getSession,();,/,如果用户没有登录,存储当前访问的页面路径后跳转到登录页面,if(,session.getAttribute(logonUser,)=null),String,requestURI,=,req.getRequestURI,();,String,contextPath,=,req.getContextPath,();,String,forwardURI,=,requestURI.substring(contextPath.length,();,session.setAttribute(viewPage,forwardURI,);,RequestDispatcher,rd=,req.getRequestDispatcher(/logon.jsp,);,rd.forward(req,response);,else,chain.doFilter(request,response);,base,href,=/,您已经登录,请先,注销,后再重新登录,!,jsp:forward,page=/,用户名或密码不正确,!,请先登录,:,姓名,:,密码,:,l,ogon.jsp,代码,LogonFilter,LogonFilter,LogonFilter,/articles/*,index.jsp,web.xml,本讲小结,什么是过滤器,:概念,用途,Filter API,:,Filter,接口、,FilterConfig,接口、,FilterChain,接口,过滤器的部署,:过滤器的声明、映射,过滤器的使用,
展开阅读全文