filter功能.它使用户可以改变一个 request和修改一个response. Filter 不是一个servlet,它不能产生一个response,它能够在一个request到达servlet之前预处理request,也可以在离开 servlet时处理response.换种说法,filter其实是一个”servlet chaining”(servlet 链).

一个filter 包括:
1. 在servlet被调用之前截获;
2. 在servlet被调用之前检查servlet request;
3. 根据需要修改request头和request数据;
4. 根据需要修改response头和response数据;
5. 在servlet被调用之后截获.

通俗点说法filter相当于加油站,request是条路,response是条路,目的地是servlet,这个加油站设在什么地方对什么数据操作可以由你来控制。

一些需要过滤器的情况:
    (1)认证Filter
    (2)日志和审核Filter
    (3)图片转换Filter
    (4)数据压缩Filter
    (5)密码Filter
    (6)令牌Filter
    (7)触发资源访问事件的Filter
    (8)XSLT Filter
    (9)媒体类型链Filter

1.批量设置请求编码

为了避免提交数据的中文乱码问题,需要在每次使用请求之前设置request.setCharacterEncoding("gb2312")编码格式,麻烦。Filter可以批量拦截修改servlet的请求和响应。

我们编写一个EncodingFilter.java,来批量设置请求编码。

public class EncodingFilter implements Filter {

public void init(FilterConfig config) throws ServletException {}

public void destroy() {}

public void doFilter(ServletRequest request,
            ServletResponse response,
            FilterChain chain)
            throws IOException, ServletException {
        request.setCharacterEncoding("gb2312");
        chain.doFilter(request, response);
    }

}

在此EncodingFilter实现了Filter接口,Filter接口中定义的三个方法都要在EncodingFilter中实现,其中doFilter()的代码实现主要的功能:

为请求设置gb2312编码并执行chain.doFilter()继续下面的操作。

转换成对应HttpServletRequest和HttpServletResponse才能进行下面的session操作和页面重定向。

与servlet相似,为了让filter发挥作用还需要在web.xml进行配置。

<filter>
     <filter-name>EncodingFilter</filter-name>
     <filter-class>sam.EncodingFilter</filter-class>
 </filter>
 
 <filter-mapping>
     <filter-name>EncodingFilter</filter-name>
     <url-pattern>/*</url-pattern>
 </filter-mapping>

filter标签部分定义使用的过滤器,filter-mapping标签告诉服务器把哪些请求交给过滤器处理。这里的/*表示所有请求,/表示根路径,*(星号)代表所有请求,加在一起就变成了根路径下的所有请求。

这样,所有的请求都会先被EncodingFilter拦截,并在请求里设置上指定的gb2312编码。

2.用filter控制用户访问权限
  出于信息安全和其他一些原因的考虑,项目中的一些页面要求用户满足了一定条件之后才能访问让用户输入帐号和密码,如果输入的信息正确就在session里做一个成功的标记,这里的成功标志就是session中的username有值;
  其后在请求保密信息的时候判断session中是否有已经登录成功的标记,存在则可以访问,不存在则禁止访问。

假设我们要保护的页面是admin/index.jsp

编写SecurityFilter.java,控制用户访问权限

public class SecurityFilter implements Filter {
public void doFilter(ServletRequest request,
        ServletResponse response,
        FilterChain chain)
        throws IOException, ServletException {
  
    HttpServletRequest req = (HttpServletRequest) request;
    HttpServletResponse res = (HttpServletResponse) response;
    HttpSession session = req.getSession();
    if (session.getAttribute("username") != null) {
        chain.doFilter(request, response);
    } else {
        res.sendRedirect("../failure.jsp");
    }
}

web.xml进行如下配置

<filter>
     <filter-name>SecurityFilter</filter-name>
     <filter-class>sam.SecurityFilter</filter-class>
 </filter>
 <filter-mapping>
     <filter-name>SecurityFilter</filter-name>
     <url-pattern>/admin/*</url-pattern>
 </filter-mapping>

定义SecurityFilter过滤器,让它过滤匹配/admin/*的所有请求,/admin/路径下的所有请求都会接受SecurityFilter的检查

因为Filter本来设计成为多种协议服务,http协议仅仅是其中一种,将ServletRequest和ServletResponse转换成HttpServletRequest和HttpServletResponse才能进行下面的session操作和页面重定向。

得到了http请求之后,可以获得请求对应的session,判断session中的username变量是否为null,如果不为null,说明用户已经登录,就可以调用doFilter继续请求访问的资源。如果为null,说明用户还没有登录,禁止用户访问,并使用页面重定向跳转到failure.jsp页面显示提示信息。

因为/failure.jsp的位置在/admin/目录的上一级,所以加上两个点才能正确跳转到failure.jsp,两个点(..)代表当前路径的上一级路径。

3.日志和审核Filter

public class LoggingFilter implements Filter {
  private FilterConfig filterConfig = null;

public void init(FilterConfig config) throws ServletException {
   this.filterConfig = config;
 }

//下面是向服务器控制台输出log,这里做的是演示,更多的是使用log4j
 public void doFilter(ServletRequest request, ServletResponse response,
   FilterChain chain) throws IOException, ServletException {
   String address = request.getRemoteAddr();
   filterConfig.getServletContext().log("User IP: " + address);
   chain.doFilter(request, response);
 }

public void destroy() {
 }
}

web.xml配置
  <filter>
   <filter-name>LoggingFilter</filter-name>
   <filter-class>samjava.filter.LoggingFilter</filter-class>
  </filter>
  <filter-mapping>
   <filter-name>LoggingFilter</filter-name>
   <url-pattern>/*</url-pattern>
  </filter-mapping>

4.filter所谓的特性
  请求映射filter-mapping和servlet-mapping都是将对应的filter或servlet映射到某个url-pattern上,当客户发起某一请求时,服务器先将此请求与web.xml中定义的所有url-pattern进行匹配,然后执行匹配通过的filter和servlet。

你可以使用三种方式定义url-pattern。

直接映射一个请求。

<servlet-mapping>
    <servlet-name>TestServlet</servlet-name>
    <url-pattern>/TestServlet</url-pattern>
</servlet-mapping>

映射一个路径下的所有请求。

<servlet-mapping>
    <servlet-name>EncodingFilter</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>

需要注意的是,这种写法必须以/开头,写成与绝对路径的形式,即便是映射所有请求也要写成/*,不能简化成*。

映射结尾相同的一类请求。

<servlet-mapping>
    <servlet-name>ControllerServlet</servlet-name>
    <url-pattern>*.do</url-pattern>
</servlet-mapping>

需要注意的是,这种请求映射就不能指定某一路径了,它必须是以星号(*)开始字母结尾,不能写成/*.do的形式。

5.过滤链
  我们使用了两个过滤器,EncodingFilter负责设置编码,SecurityFilter负责控制权限,那这两个过滤器是怎么起作用的呢?

所有的奥秘就在Filter中的FilterChain中。服务器会按照web.xml中过滤器定义的先后循序组装成一条链,然后一次执行其中的doFilter()方法。执行的顺序就如上图所示,执行第一个过滤器的chain.doFilter()之前的代码,第二个过滤器的chain.doFilter()之前的代码,请求的资源,第二个过滤器的chain.doFilter()之后的代码,第一个过滤器的chain.doFilter()之后的代码,最后返回响应。

代码执行顺序是:

(1)执行EncodingFilter.doFilter()中chain.doFilter()之前的部分:request.setCharacterEncoding("gb2312");

(2)执行SecurityFilter.doFilter()中chain.doFilter()之前的部分:判断用户是否已登录

(3)如果用户已登录,则访问请求的资源:/admin/index.jsp

(4)如果用户未登录,则页面重定向到:/failure.jsp

(5)执行SecurityFilter.doFilter()中chain.doFilter()之后的部分;

(6)执行EncodingFilter.doFilter()中chain.doFilter()之后的部分;

说的简单点就是filter将按照在web.xml文件中的声明顺序调用。

过滤链的好处是,执行过程中任何时候都可以打断,只要不执行chain.doFilter()就不会再执行后面的过滤器和请求的内容。
  要特别注意过滤链的执行顺序问题,像EncodingFilter就一定要放在所有Filter之前(在web.xml文件中),这样才能确保在使用请求中的数据前设置正确的编码。

6.filter的详细配置
  我们已经了解了filter的基本用法,还有一些细节配置在特殊情况下起作用。

在servlet-2.3中,Filter会过滤一切请求,包括服务器内部使用forward转发请求和<%@ include file="/index.jsp"%>的情况。

到了servlet-2.4中Filter默认下只拦截外部提交的请求,forward和include这些内部转发都不会被过滤,但是有时候我们需要forward的时候也用到Filter,这样就需要如下配置。

<filter>
    <filter-name>TestFilter</filtername>
    <filter-class>sam.TestFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>TestFilter</filtername>
    <url-pattern>/*</url-pattern>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>INCLUDE</dispatcher>
    <dispatcher>EXCEPTION</dispatcher>
</filter-mapping>

这样TestFilter就会过滤所有状态下的请求。如果我们没有进行设置,默认使用的就是REQUEST。而EXCEPTION是在isErrorPage="true"的情况下出现的,这个用处不多,看一下即可。

这里FORWARD是解决request.getDispatcher("index.jsp").forward(request, response);无法触发Filter的关键,配置上这个以后再进行forward的时候就可以触发过滤器了。

Filter过滤器的更多相关文章

  1. filter 过滤器(监听)

    Filter 过滤器 1.简介 Filter也称之为过滤器,它是Servlet技术中最实用的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, ...

  2. Java防止SQL注入2(通过filter过滤器功能进行拦截)

    首先说明一点,这个过滤器拦截其实是不靠谱的,比如说我的一篇文章是介绍sql注入的,或者评论的内容是有关sql的,那会过滤掉:且如果每个页面都经过这个过滤器,那么效率也是非常低的. 如果是要SQL注入拦 ...

  3. Filter(过滤器)学习

    一.Filter简介 Filter也称之为过滤器,它是Servlet技术中最激动人心的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态 ...

  4. javaweb学习总结(四十二)——Filter(过滤器)学习

    一.Filter简介 Filter也称之为过滤器,它是Servlet技术中最激动人心的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态 ...

  5. Filter过滤器简单应用( 接口访问控制 )

    一.描述 在提供安卓.IOS客户端接口时,可以在登陆接口分配Session给客户端,用于判断其他接口是否是合法访问,以避免将所有的接口都暴露在web中可以由路径直接访问.但是最近的一个项目中的移动接口 ...

  6. 如何配置Filter过滤器处理JSP中文乱码

    参考Tomcat服务器目录webapps的examples示例 简单配置步骤:1.在项目web.xml文件添加过滤器标记<filter>和<filter-mapping>:2. ...

  7. Filter(过滤器)常见应用

    孤傲苍狼 只为成功找方法,不为失败找借口! javaweb学习总结(四十六)——Filter(过滤器)常见应用 一.统一全站字符编码 通过配置参数charset指明使用何种字符编码,以处理Html F ...

  8. Filter过滤器(1)

    Filter也称之为过滤器,它是Servlet技术中比较激动人心的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 ht ...

  9. Servlet的学习之Filter过滤器技术(1)

    本篇将讲诉Servlet中一项非常重要的技术,Filter过滤器技术.通过过滤器,可以对来自客户端的请求进行拦截,进行预处理或者对最终响应给客户端的数据进行处理后再输出. 要想使用Filter过滤器, ...

  10. javaWeb学习总结(10)- Filter(过滤器)学习

    一.Filter简介 Filter也称之为过滤器,它是Servlet技术中最激动人心的技术,WEB开发人员通过Filter技术,对web服务器管理的所有 web资源:例如Jsp, Servlet, 静 ...

随机推荐

  1. IPC是什么意思?

    IPC(Inter-Process Communication,进程间通信)IPC ( Instruction per Clock 及CPU每一时钟周期内所执行的指令多少) IPC代表了一款处理器的设 ...

  2. Android 系统的四层结构

    从上图中可以看出,Android 系统架构为四层结构,从上层到下层分别是应用程序层(Applications). 应用程序框架层 (Application Framework).系统运行库层(Libr ...

  3. python 中@property的使用

    从14年下半年开始接触到python,自学了一段时间,后又跟别人学习了下,把基础知识基本上学过了.忽然感觉python不可能这么简单吧,就这么点东西?后来看了下书,发现还有很多的高级部分.连续看了两天 ...

  4. IT国家重点实验室

    软件工程国家重点实验室(武汉大学): http://www.sklse.whu.edu.cn/ 南京大学: http://keysoftlab.nju.edu.cn/ 水声技术国家重点实验室 http ...

  5. bzoj1030

    AC自动机和DP. f[i][j] 表示在匹配到第i位置,处于ac自动机的j节点.决策第(i+1)个字母,计算出转移到第j2节点. f[i+1][j2] += f[i][j]; #include< ...

  6. 手动启动angular

    关于手动启动 angular 的问题 angular核心原理解析1:angular自启动过程 angular.element(document).ready(function() { angular. ...

  7. EasyUI 添加tab页(iframe方式)

    function addTab(title, href,icon){ var tt = $('#tabs'); if (tt.tabs('exists', title)){//如果tab已经存在,则选 ...

  8. Ehcache和MemCached比较分析

    项目 Memcache Ehcache 分布式 不完全,集群默认不实现 支持 集群 可通过客户端实现 支持(默认是异步同步) 持久化 可通过第三方应用实现,如sina研发的memcachedb,将ca ...

  9. 【原创】batch-GD, SGD, Mini-batch-GD, Stochastic GD, Online-GD -- 大数据背景下的梯度训练算法

    机器学习中梯度下降(Gradient Descent, GD)算法只需要计算损失函数的一阶导数,计算代价小,非常适合训练数据非常大的应用. 梯度下降法的物理意义很好理解,就是沿着当前点的梯度方向进行线 ...

  10. Can not perform pod install under el capitan (15A279b)

    这个问题在stackoverflow上面有过讨论: Can not perform pod install under el capitan (15A279b) 被采纳的答案为:sudo gem in ...