⑧javaWeb之在例子中学习(过滤器Filter) 前言

Fitler(过滤器)

  过滤器filter是拦截请求,并对传给请求资源的ServletRequest 或 ServletResponse 进行处理的一个对象。可以用于登录,加密和解密,会话检查,图片转换等等

 

  过滤器执行机制图:

      

   

  Filter API : http://docs.oracle.com/javase/6/docs/api/

Filter详解

  Filter接口的构成:

        所有的Filter类都必须实现javax.servlet.Filter接口。这个接口含有3个过滤器类必须实现的方法:

 

          ①init(FilterConfig):这是Filter的初始化方法,Servlet容器创建Filter实例后将调用这个方法。在这个方法中可以读取web.xml文件中Filter的初始化参数

        
  ②doFilter(ServletRequest,ServletResponse,FilterChain): 这个方法完成实际的过滤操作,当
客户请求访问于Filter关联的URL时,Servlet容器将先调用Filter的doFilter方法。FilterChain参数用于访问后续
Filters

          ③destroy():  Servlet容器在销毁Filter实例前调用该方法,这个方法中可以释放Filter占用的资源

 

       配置Filter(下面例子用的是注释配置)

<filter>
    <filter-name>enconfigFilter</filter-name>
    <filter-class>com.filter.EnconfigFilter</filter-class>
    <init-param>
        <param-name>enconfig</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>enconfigFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

       其中:   

        filter-name   指定过滤器的名字
        filter-class    指定过滤器的类名
        init-param    为过滤器实例提供初始化参数,可以有多个
        url-pattern   指定和过滤器关联的URL,为”/*”表示所有URL

 

图片保护过滤器

  咱们用ImageProtetorFilter来保护咱们的图片,防止地址栏中直接输入图片URL 来下载图片。

 

  小小的原理:

    过滤器通过查看HTTP 标头的referer的值进行工作。值为空表示当前请求没有相当的引用页。而值为空,说明请求在引用页,自然图片在jsp里面供认看与下载。

  

  小朽尝试:

    ①包结构

      

    ② ImageProtector类

      doFilter实现了,获取标头→判断→然后抛异常

    

package sedion.jeffli.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;

/**
 *
 * @author Jeff Li
 *
 */
@WebFilter(filterName = "ImageProtetorFilter",urlPatterns={"*.png","*.jpg","*.gif"})
public class ImageProtector implements Filter{

    @Override
    public void destroy() {
        // TODO Auto-generated method stub

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        System.out.println("ImageProtetorFilter");
        HttpServletRequest httpServletR = (HttpServletRequest)request;
        String referrer = httpServletR.getHeader("referer");
        System.out.println("referrer:"+referrer);
        if(referrer != null){
            chain.doFilter(request, response);
        }else{
            throw new ServletException("Image not available");
        }

    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // TODO Auto-generated method stub

    }

}

    

    ③JSP 页面加入

<img alt="logo" src="logo.jpg">

 

  小朽看效果说话:

    ①当直接在火狐中,打开url:http://localhost:8080/filterTest/logo.jpg

      页面出现了 HTTP Status 500 - Image not available

      打开小蜜蜂(firebug),查看网络,发现没有referer请求头信息

    ②当直接在火狐中,打开url:http://localhost:8080/filterTest/index.jsp

      页面自然出现了图片。

      打开小蜜蜂(firebug),查看网络

        

 

下载过滤器

  顾名思义,计算某个资源下载了多少次,或知道某些东石受欢迎程度。自然这个必不可少。

  Question and Solving:

    我们将值保存在一个属性文件中,并且多个线程可以同时访问一个过滤器,因此就有一个线程安全性的问题需要解决。用户请求资源读取相应属性
值,将它赠一个并存回新值。如果第一个线程完成任务前,又有第二个用户请求同一个资源,怎么办?同步读写值的代码似乎不是个好方法,涉及到扩展性的问题。

    我们利用Queue 和 Executor 解决这个线程的问题。所有进来的请求都在一个线程Executor队列中放置一项任务。放置任务比较快,因为这是一个异步的操作。由于只有使用一个Executor一个线程,因此消除了多线程访问该属性文件的可能。

  

  小朽尝试:

    就加个DownloadCounterFilter,启动就好。

package sedion.jeffli.filter;

import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
/**
 *
 * @author Jeff Li
 *
 */

@WebFilter(filterName="DownloadCounterFilter",urlPatterns={"/*"})
public class DownloadCounterFilter implements Filter{

    ExecutorService executorService = Executors.newSingleThreadExecutor();
    Properties downloadLog;
    File logFile;

    @Override
    public void destroy() {
        executorService.shutdown();
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;

        final String uri = httpServletRequest.getRequestURI();
        executorService.execute(new Runnable() {

            @Override
            public void run() {
                String property = downloadLog.getProperty(uri);

                if(property == null){
                    downloadLog.setProperty(uri, "1");
                }else{
                    int count = 0;
                    try {
                        count = Integer.parseInt(property);
                    } catch (NumberFormatException e) {
                    }
                    count++;
                    downloadLog.setProperty(uri, Integer.toString(count));
                }

                try {
                    downloadLog.store(new FileWriter(logFile), "");
                } catch (Exception e) {
                }
            }
        });

        chain.doFilter(request, response);
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("DownloadCounterFilter");
        String appPath = filterConfig.getServletContext().getRealPath("/");
        logFile = new File(appPath,"downloadLog.txt");

        if(!logFile.exists()){
            try {
                logFile.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        downloadLog = new Properties();
        try {
            downloadLog.load(new FileReader(logFile));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

    

  小朽分析下:

  

String appPath = filterConfig.getServletContext().getRealPath("/");
        logFile = new File(appPath,"downloadLog.txt");

        if(!logFile.exists()){
            try {
                logFile.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

   项目路径下:tomcat_dir/filterTest/ 如果没有文件downloadLog.txt,初始化生成。当访问项目有关文件,则会记录到这个property文件中。

   

    小朽看效果:

    打开tomcat_dir/filterTest/downloadLog.txt

#
#Thu Mar 20 12:39:02 CST 2014
/filterTest/logo.jpg=3
/filterTest/=1
/filterTest/index.jsp=2
时间: 2024-08-03 06:18:19

⑧javaWeb之在例子中学习(过滤器Filter) 前言的相关文章

在实际例子中学习正则表达式(高效率)_正则表达式

  正则表达式简介 正则表达式,又称正规表示法.常规表示法.(英语:Regular Expression,在代码中常简写为regex.regexp或RE),计算机科学的一个概念.正则表达式使用单个字符串来描述.匹配一系列符合某个句法规则.在很多文本编辑器里,正则表达式通常被用来检索.替换那些符合某个模式的文本. 最近整体学习了一下正则表达式的知识,发现还是在例子中进行学习效率比较高,接下来分享一下正则表达式的经典例子并进行相关知识点的总结. 例子1:匹配5-12位的数字:^\d{5,12}$ 首

在实际例子中学习正则表达式(高效率)

正则表达式简介 正则表达式,又称正规表示法.常规表示法.(英语:Regular Expression,在代码中常简写为regex.regexp或RE),计算机科学的一个概念.正则表达式使用单个字符串来描述.匹配一系列符合某个句法规则.在很多文本编辑器里,正则表达式通常被用来检索.替换那些符合某个模式的文本. 最近整体学习了一下正则表达式的知识,发现还是在例子中进行学习效率比较高,接下来分享一下正则表达式的经典例子并进行相关知识点的总结. 例子1:匹配5-12位的数字:^\d{5,12}$ 首先介

AngularJS中的过滤器filter用法完全解析_AngularJS

在AngularJS的世界里,filter提供了一种格式化数据的方法,Angular也提供给我们了很多内建的过滤器,并且建立自定义过滤器也是相当的简单 在HTML的模板绑定{{}}中,我们使用 | 来调用过滤器,比如,我们想让字符串全部大写字符显示: {{ name | uppercase }} 当然了,我们也可以在JavaScript中使用$filter服务来调用过滤器,还拿字符串大写来举例: app.controller('DemoController', ['$scope', '$filt

Lucene5学习之Filter过滤器

  清明3天假,我猜小伙伴们都相约出去玩去了,对于我等屌丝来说,唯有在家写代码打发时间了.其实不是我喜欢宅,只是一个人去哪儿都没有激情,还不如在家安安静静的看看书写写代码来的安逸,对这个看脸的世界就差绝望了,就算代码虐我千万遍,我待代码还是如初恋啊!今天从早上9点起来,就中午做个饭,一坐就是整整10个小时,照着我预想的计划继续记录我的Lucene5学习轨迹,由于Filter体系下子类有点多,还要编写测试demo,所以这篇博客有点姗姗来迟,请大家多多包涵!                    

AngularJS过滤器filter用法总结_AngularJS

本文实例总结了AngularJS过滤器filter用法.分享给大家供大家参考,具体如下: 引言 filter过滤器对于我们来说并不陌生,他和我们现实生活中的过滤器的意思差不多,它的作用就是接收一个输入的值,然后按照某个规则进行处理然后输出最后的结果,例如我们输入一个数字,然后我们需要得到货币形式的数据,这样我们就可以利用过滤器来实现,AngularJS中的过滤器是非常简单的,分为内置和自定义两种,下面小编就简单的给大家介绍一些. 内置过滤器 ng内置了一些过滤器,它们是:currency(货币)

servlet和JSP过滤器Filter

js|servlet 或许,servlet API的2.3版本中最重要的一个新功能就是能够为servlet和JSP页面定义过滤器.过滤器提供了某些早期服务器所支持的非标准"servlet链接"的一种功能强大且标准的替代品.过滤器是一个程序,它先于与之相关的servlet或JSP页面运行在服务器上.过滤器可附加到一个或多个servlet或JSP页面上,并且可以检查进入这些资源的请求信息.在这之后,过滤器可以作如下的选择:l 以常规的方式调用资源(即,调用servlet或JSP页面).l

AngularJS中的过滤器使用详解

  这篇文章主要介绍了AngularJS中的过滤器使用详解,过滤器是AngularJS中处理文本的一个非常有用的功能,需要的朋友可以参考下 过滤器是用来更改修改数据,并且可以在表达式或使用管道符指令将其归入.以下是常用的过滤器的列表. 小写过滤器 添加小写的过滤器,使用管道符的表达式.在这里添加小写过滤器,以小写字母打印学生姓名. ? 1 2 3 Enter first name:<input type="text" ng-model="student.firstNam

PHP中实现Bloom Filter算法

 这篇文章主要介绍了PHP中实现Bloom Filter算法,本文直接给出实现代码,代码中给出详细注释,Bloom Filter算法介绍等内容,需要的朋友可以参考下     ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57

《深入理解ElasticSearch》——2.8 ElasticSearch切面机制中的过滤器与作用域

2.8 ElasticSearch切面机制中的过滤器与作用域 当使用ElasticSearch的切面机制时,有几件事情需要注意.首先要记住的是,系统只在查询结果之上计算切面结果.如果你在filter对象内部且在query对象外部包含了过滤器,那么这些过滤器将不会对参与切面计算的文档产生影响.另外一个需要注意的事情是作用域(scope),它能扩充用于切面计算的文档.接下来我们来看几个范例.2.8.1 范例数据先回忆一下查询.过滤器.切面是如何一起工作的.为了演示该功能,我们先使用下面的命令索引一些