1、北京传智播客教育 ,Filter简介,Servlet API中提供了一个Filter接口,开发web应用时,如果编写的Java类实现了这个接口,则把这个java类称之为过滤器Filter。通过Filter技术,开发人员可以实现用户在访问某个目标资源之前,对访问的请求和响应进行拦截,如下所示: 过滤器通常也被称作拦截器,Web浏览器,Web服务器,web资源 Jsp Servlet html,过滤器,北京传智播客教育 ,Filter是如何实现拦截的?,Filter接口中有一个doFilter方法,开发人员编写的Filter需要实现此方法WEB服务器每次在调用servlet的service方法之前
2、,会在xml文件中查找当前url地址是否被拦截,如果有,会调用对应的filter对象的doFilter方法编写好的Filter必须在web.xml中做映射,说明拦截的url地址,此filter才能起作用web服务器在调用doFilter方法时,会传递一个filterChain对象进来,filterChain对象是filter接口中最重要的一个对象,它也提供了一个doFilter方法,开发人员可以根据需求决定是否调用此方法,调用该方法,相当于过滤器放行,web服务器就会继续调用servlet的service方法,即web资源就会被访问,否则web资源不会被访问。,北京传智播客教育 ,实现第一个F
3、ilter程序,Filter开发分为二个步骤: 编写java类实现javax.servlet.Filter接口,并实现其doFilter方法。 在 web.xml 文件中使用和元素对编写的filter类进行注册,并设置它所能拦截的资源Filter链 在一个web应用中,可以开发编写多个Filter,这些Filter组合起来称之为一个Filter链。web服务器根据Filter在web.xml文件中的注册顺序,决定先调用哪个Filter,当第一个Filter的doFilter方法被调用时,相当于Filter链的当前拦截器放行,web服务器会访问下一个Filter当链上所有的Filter都放行了,
4、web服务器才会访问目标资源,北京传智播客教育 ,Filter的生命周期,Init方法 服务器创建一个Filter对象时会自动调用对象的init方法 通过init(FilterConfig filterConfig)方法可以获得Filter的初始化参数destroy方法 在Web容器卸载 Filter 对象之前被调用,该方法主要用于释放Filter 占用的资源,北京传智播客教育 ,Filter案例一,统一全站字符编码的过滤器 response.setCharacterEncoding(“utf-8”); response.setContentType(“text/html;charset=ut
5、f-8”);,北京传智播客教育 ,Filter案例二,禁止浏览器缓存所有动态页面的过滤器 有 3 个 HTTP 响应头字段都可以禁止浏览器缓存当前页面,它们在 Servlet 中的示例代码如下: response.setDateHeader(“Expires“,-1); response.setHeader(“Cache-Control“,“no-cache“); response.setHeader(“Pragma“,“no-cache“); 并不是所有的浏览器都能完全支持上面的三个响应头,因此最好是同时使用上面的三个响应头。 Expires数据头:值为GMT时间值,为-1指浏览器不要缓存页
6、面 Cache-Control响应头有两个常用值: no-cache指浏览器不要缓存当前页面。 max-age:xxx指浏览器缓存页面xxx秒。,北京传智播客教育 ,Filter案例三,控制浏览器缓存页面中的静态资源的过滤器场景:有些动态页面中引用了一些图片或css文件以修饰页面效果,这些图片和css文件经常是不变化的,所以为减轻服务器的压力,可以使用filter控制浏览器缓存这些文件,以提升服务器的性能。对有可能需要缓存的资源进行拦截通过设置Expires头通知浏览器将页面进行缓存通过读取配置文件获得不同格式文件的缓存时间,北京传智播客教育 ,Filter案例四,实现用户自动登陆的过滤器在用
7、户登陆成功后,发送一个名称为user的cookie给客户端,cookie的值为用户名和md5加密后的密码。编写一个AutoLoginFilter,这个filter检查用户是否带有名称为user的cookie来,如果有,则调用dao查询cookie的用户名和密码是否和数据库匹配,匹配则向session中存入user对象(即用户登陆标记),以实现程序完成自动登陆。,北京传智播客教育 ,Filter的部署注册Filter,testFitlerorg.test.TestFiterword_file /WEB-INF/word.txt,用于为过滤器指定一个名字,该元素的内容不能为空。 元素用于指定过滤器
8、的完整的限定类名。 元素用于为过滤器指定初始化参数,它的子元素指定参数的名字,指定参数的值。在过滤器中,可以使用FilterConfig接口对象来访问初始化参数。,北京传智播客教育 ,Filter的部署映射Filter,元素用于设置一个 Filter 所负责拦截的资源。一个Filter拦截的资源可通过两种方式来指定:Servlet 名称和资源访问的请求路径 子元素用于设置filter的注册名称设置 filter 所拦截的请求路径(过滤器关联的URL样式)指定过滤器所拦截的Servlet名称指定过滤器所拦截的资源被 Servlet 容器调用的方式,可以是REQUEST,INCLUDE,FORWA
9、RD和ERROR之一,默认REQUEST。用户可以设置多个 子元素用来指定 Filter 对资源的多种调用方式进行拦截,北京传智播客教育 ,Filter的部署映射Filter, 子元素可以设置的值及其意义:REQUEST:当用户直接访问页面时,Web容器将会调用过滤器。如果目标资源是通过RequestDispatcher的include()或forward()方法访问时,那么该过滤器就不会被调用。 INCLUDE:如果目标资源是通过RequestDispatcher的include()方法访问时,那么该过滤器将被调用。除此之外,该过滤器不会被调用。 FORWARD:如果目标资源是通过Reque
10、stDispatcher的forward()方法访问时,那么该过滤器将被调用,除此之外,该过滤器不会被调用。 ERROR:如果目标资源是通过声明式异常处理机制调用时,那么该过滤器将被调用。除此之外,过滤器不会被调用。,北京传智播客教育 ,Filter高级应用-装饰模式,由于开发人员在filter中可以得到代表用户请求和响应的request、response对象,因此在编程中可以使用Decorator(装饰器)模式对request、response对象进行包装,再把包装对象传给目标资源,从而实现一些特殊需求。,北京传智播客教育 ,Decorator设计模式(装饰模式),在程序中需要自定义一个类对
11、原有的类进行功能的增强,此时可以使用包装设计模式,又称装饰模式包装设计模式具有以下特点: 以对用户程序透明的方式,动态地给一个对象附加上更多的功能,或者修改这个对象的部分功能 假定类A是类B的包装类,那么类A与类B需要实现相同的接口说白了,被包装的是什么,包装完了还应该是什么 类A需要拥有一个类B的实例,通过构造函数组合进来 类A借助类B的实例来实现接口的抽象方法,自己实现需要增强的方法即可,北京传智播客教育 ,request、response对象的增强,为了方便开发人员对request对象进行包装,Servlet API 中提供了一个request对象默认包装类HttpServletRequ
12、estWrapper HttpServletRequestWrapper 类实现了request 接口中的所有方法,但这些方法的内部实现都是仅仅调用了一下所包装的的 request 对象的对应方法我们在程序中通过继承默认包装类对request对象进行增强,重写需要增强的方法。同样地,response也有默认的包装类 HttpServletResponseWrapper,北京传智播客教育 ,request对象的增强案例,使用Decorator模式包装request对象,完全解决get、post请求方式下的乱码问题。使用Decorator模式包装request对象,实现html标签转义功能(Tom
13、cat服务器中提供了转义html标签的工具类)。,北京传智播客教育 ,response增强案例压缩响应,应用HttpServletResponseWrapper对象,压缩响应正文内容。思路: 通过filter向目标页面传递一个自定义的response对象。 在自定义的response对象中,重写getOutputStream方法和getWriter方法,使目标资源调用此方法输出页面内容时,获得的是我们自定义的ServletOutputStream对象。 在我们自定义的ServletOuputStream对象中,重写write方法,使写出的数据写出到一个buffer中。 当页面完成输出后,在filter中就可得到页面写出的数据,从而我们可以调用GzipOuputStream对数据进行压缩后再写出给浏览器,以此完成响应正文件压缩功能。,实用案例用户权限管理,为用户分配权限检查用户权限,