ServletFilter过滤器(二)

来源:互联网 发布:php 异步请求网页 编辑:程序博客网 时间:2024/05/16 03:30

Filter常见应用(3)

控制浏览器缓存页面中的静态资源的过滤器:

场景:有些动态页面中引用了一些图片或css文件以修饰页面效果,这些图片和css文件经常是不变化的,所以为减轻服务器的压力,可以使用filter控制浏览器缓存这些文件,以提升服务器的性能。

Filter常见应用(4)

使用Filter实现URL级别的权限认证

情景:在实际开发中我们经常把一些执行敏感操作的servlet映射到一些特殊目录中,并用filter把这些特殊目录保护起来,限制只能拥有相应访问权限的用户才能访问这些目录下的资源。从而在我们系统中实现一种URL级别的权限功能。

要求:为使Filter具有通用性,Filter保护的资源和相应的访问权限通过filter参数的形式予以配置。

Filter常见应用(5)

实现用户自动登陆的过滤器

在用户登陆成功后,发送一个名称为usercookie给客户端,cookie的值为用户名和md5加密后的密码。

编写一个AutoLoginFilter,这个filter检查用户是否带有名称为usercookie来,如果有,则调用dao查询cookie的用户名和密码是否和数据库匹配,匹配则向session中存入user对象(即用户登陆标记),以实现程序完成自动登陆。

Filter的部署—注册Filter

<filter>

       <filter-name>testFitler</filter-name>

     <filter-class>org.test.TestFiter</filter-class>

     <init-param>

 <param-name>word_file</param-name>

 <param-value>/WEB-INF/word.txt</param-value>

     </init-param>

</filter>

<filter-name>用于为过滤器指定一个名字,该元素的内容不能为空。

<filter-class>元素用于指定过滤器的完整的限定类名。

<init-param>元素用于为过滤器指定初始化参数,它的子元素<param-name>指定参数的名字,<param-value>指定参数的值。在过滤器中,可以使用FilterConfig接口对象来访问初始化参数。

Filter的部署—映射Filter

<filter-mapping>元素用于设置一个 Filter 所负责拦截的资源。一个Filter拦截的资源可通过两种方式来指定:Servlet 名称和资源访问的请求路径

<filter-name>子元素用于设置filter的注册名称。该值必须是在<filter>元素中声明过的过滤器的名字

<url-pattern>设置 filter 所拦截的请求路径(过滤器关联的URL样式)

<servlet-name>指定过滤器所拦截的Servlet名称。

<dispatcher>指定过滤器所拦截的资源被 Servlet 容器调用的方式,可以是REQUEST,INCLUDE,FORWARDERROR之一,默认REQUEST。用户可以设置多个<dispatcher> 子元素用来指定 Filter 对资源的多种调用方式进行拦截。

<dispatcher> 子元素可以设置的值及其意义:

REQUEST:当用户直接访问页面时,Web容器将会调用过滤器。如果目标资源是通过RequestDispatcherinclude()forward()方法访问时,那么该过滤器就不会被调用。

INCLUDE:如果目标资源是通过RequestDispatcherinclude()方法访问时,那么该过滤器将被调用。除此之外,该过滤器不会被调用。

FORWARD:如果目标资源是通过RequestDispatcherforward()方法访问时,那么该过滤器将被调用,除此之外,该过滤器不会被调用。

ERROR:如果目标资源是通过声明式异常处理机制调用时,那么该过滤器将被调用。除此之外,过滤器不会被调用。

TipFilter的部署—映射Filter示例

<filter-mapping>

     <filter-name>testFilter</filter-name>

    <url-pattern>/test.jsp</url-pattern>

</filter-mapping>

<filter-mapping>

    <filter-name>testFilter</filter-name>

   <url-pattern>/index.jsp</url-pattern>

   <dispatcher>REQUEST</dispatcher>

   <dispatcher>FORWARD</dispatcher>

</filter-mapping>

TipFilter高级开发

由于开发人员在filter中可以得到代表用户请求和响应的requestresponse对象,因此在编程中可以使用Decorator(装饰器)模式对requestresponse对象进行包装,再把包装对象传给目标资源,从而实现一些特殊需求。

Decorator设计模式

当某个对象的方法不适应业务需求时,通常有2种方式可以对方法进行增强:

编写子类,覆盖需增强的方法

使用Decorator设计模式对方法进行增强

疑问:在实际应用中遇到需增强对象的方法时,到底选用哪种方式呢?

没有具体的定式,不过有一种情况下,必须使用Decorator设计模式:即被增强的对象,开发人员只能得到它的对象,无法得到它的class文件。

比如requestresponse对象,开发人员之所以在servlet中能通过sun公司定义的HttpServletRequest\response接口去操作这些对象,是因为Tomcat服务器厂商编写了requestresponse接口的实现类。web服务器在调用servlet时,会用这些接口的实现类创建出对象,然后传递给servlet程序。

此种情况下,由于开发人员根本不知道服务器厂商编写的requestresponse接口的实现类是哪个?在程序中只能拿到服务器厂商提供的对象,因此就只能采用Decorator设计模式对这些对象进行增强。

request对象的增强

Servlet API 中提供了一个request对象的Decorator设计模式的默认实现类HttpServletRequestWrapper , (HttpServletRequestWrapper 类实现了request 接口中的所有方法,但这些方法的内部实现都是仅仅调用了一下所包装的的 request 对象的对应方法)以避免用户在对request对象进行增强时需要实现request接口中的所有方法。

response对象的增强

Servlet  API 中提供了response对象的Decorator设计模式的默认实现类HttpServletResponseWrapper , (HttpServletResponseWrapper类实现了response接口中的所有方法,但这些方法的内部实现都是仅仅调用了一下所包装的的 response对象的对应方法)以避免用户在对response对象进行增强时需要实现response接口中的所有方法。

response增强案例—压缩响应

应用HttpServletResponseWrapper对象,压缩响应正文内容。思路:

通过filter向目标页面传递一个自定义的response对象。

在自定义的response对象中,重写getOutputStream方法和getWriter方法,使目标资源调用此方法输出页面内容时,获得的是我们自定义的ServletOutputStream对象。

在我们自定义的ServletOuputStream对象中,重写write方法,使写出的数据写出到一个buffer中。

当页面完成输出后,在filter中就可得到页面写出的数据,从而我们可以调用GzipOuputStream对数据进行压缩后再写出给浏览器,以此完成响应正文件压缩功能。