`

Jsp Filter详解

 
阅读更多

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的时候就可以触发过滤器了。

分享到:
评论

相关推荐

    JAVA WEB 开发详解:XML+XSLT+SERVLET+JSP 深入剖析与实例应用.part2

    本书共分4部分,从xml、servlet、jsp和应用的角度向读者展示了java web开发中各种技术的应用,循序渐进地引导读者快速掌握java web开发。.  本书内容全面,涵盖了从事java web开发所应掌握的所有知识。在知识的讲解...

    JAVA WEB 开发详解:XML+XSLT+SERVLET+JSP 深入剖析与实例应用.part3

    本书共分4部分,从xml、servlet、jsp和应用的角度向读者展示了java web开发中各种技术的应用,循序渐进地引导读者快速掌握java web开发。.  本书内容全面,涵盖了从事java web开发所应掌握的所有知识。在知识的讲解...

    JAVA WEB 开发详解:XML+XSLT+SERVLET+JSP 深入剖析与实例应用.part4

    本书共分4部分,从xml、servlet、jsp和应用的角度向读者展示了java web开发中各种技术的应用,循序渐进地引导读者快速掌握java web开发。.  本书内容全面,涵盖了从事java web开发所应掌握的所有知识。在知识的讲解...

    jsp filter 过滤器功能与简单用法示例

    主要介绍了jsp filter 过滤器功能与简单用法,结合实例形式详细分析了jsp filter 过滤器的功能、使用方法及操作注意事项,需要的朋友可以参考下

    JAVA WEB 开发详解:XML+XSLT+SERVLET+JSP 深入剖析与实例应用.part5

    本书共分4部分,从xml、servlet、jsp和应用的角度向读者展示了java web开发中各种技术的应用,循序渐进地引导读者快速掌握java web开发。.  本书内容全面,涵盖了从事java web开发所应掌握的所有知识。在知识的讲解...

    servlet过滤器详解

    jsp中servlet的过滤器详解,在网上找了很久,这个是最清楚最简单的,容易入门,也能明白他的概念

    Java Web整合开发王者归来(JSP+Servlet+Struts+Hibernate+Spring)

    第2篇为基础篇,内容包括Servlet技术、JSP技术、会话跟踪、过滤器Filter、监听器Listener等;第3篇为高级篇,内容包括JSTL标签库的使用、如何自定义标签、资源国际化、数据库概述、JDBC详解、XML概述等;第4篇为...

    详解JSP中使用过滤器进行内容编码的解决办法

    详解JSP中使用过滤器进行内容编码的解决办法 问题 当通过JSP页面,向数据库中插入记录的时候,可能因为JSP页面编码原因,导致插入到数据库中的新纪录出现乱码。因此需要对JSP页面中的内容进行编码操作,从而保证与...

    Web配置详解

    jsp的web.xml配置说明 Web.xml常用元素&lt;web-app&gt;&lt;display-name&gt;定义了WEB应用的名字...&lt;filter-mapping&gt;&lt;/filter-mapping&gt; 一旦命名了一个过滤器,就要利用filter-mapping元素把它与一个或多个servlet或JSP页面相关联。

    Filter_Listener相信代码使用

    package com.chinasofti.filter; import java.io.IOException; import javax.servlet.Filter;... request.getRequestDispatcher("error.jsp").forward(request, response); 里面有更详细的代码。。。

    JavaWeb Servlet中Filter过滤器的详解

    主要介绍了JavaWeb Servlet中Filter过滤器的详解的相关资料,希望通过本文能帮助到大家,让大家彻底掌握如何使用,需要的朋友可以参考下

    java web 开发详解

    但基本也都是遵循特定的路数的:使用Servlet或者Filter拦截请求,使用MVC的思想设计架构,使用约定,XML或 Annotation实现配置,运用Java面向对象的特点,面向抽象实现请求和响应的流程,支持Jsp,Freemarker,...

    J2EE应用开发详解

    57 4.3.7 Servlet协作 57 4.3.8 Filter 58 4.4 使用Servlet处理客户端请求 58 4.5 会话跟踪 61 4.5.1 使用Cookie进行会话跟踪 61 4.5.2 使用URL重写进行会话跟踪 62 4.5.3 使用隐藏表单域进行会话跟踪 63 4.6 小结 ...

    jsp中过滤器选择过滤器的写法详解

    public class LoginCheckFilter implements Filter { private FilterConfig config=null; private String webroot=null; public void destroy() { // TODO Auto-generated method stub } @Override public void ...

    web.xml详细说明

    用于 web.xml 配置详解。例如: &lt;display-name&gt;&lt;/display-name&gt;定义了WEB应用的...&lt;filter-mapping&gt;&lt;/filter-mapping&gt; 一旦命名了一个过滤器,就要利用filter-mapping元素把它与一个或多个servlet或JSP页面相关联。

    Ajax+Struts1.x 登陆程序源代码(详解)

    包含内容: ...字符编码Filter JDBC封装连接类 各个配置文件 各个JSP文件 ... 总之,就是整个AJAX+STRUTS项目登陆程序打包,可以在ECLIPSE下导入,在TOMCAT5.X下运行(这需要将下载包当中的sql先执行)

    Java.Web整合开发王者归来.part04.rar

    第2篇为基础篇,内容包括Servlet技术、JSP技术、会话跟踪、过滤器Filter、监听器Listener等;第3篇为高级篇,内容包括JSTL标签库的使用、如何自定义标签、资源国际化、数据库概述、JDBC详解、XML概述等;第4篇为...

    Java.Web整合开发王者归来.part02.rar

    第2篇为基础篇,内容包括Servlet技术、JSP技术、会话跟踪、过滤器Filter、监听器Listener等;第3篇为高级篇,内容包括JSTL标签库的使用、如何自定义标签、资源国际化、数据库概述、JDBC详解、XML概述等;第4篇为...

    Java.Web整合开发王者归来.part05.rar

    第2篇为基础篇,内容包括Servlet技术、JSP技术、会话跟踪、过滤器Filter、监听器Listener等;第3篇为高级篇,内容包括JSTL标签库的使用、如何自定义标签、资源国际化、数据库概述、JDBC详解、XML概述等;第4篇为...

    Java.Web整合开发王者归来.part03.rar

    第2篇为基础篇,内容包括Servlet技术、JSP技术、会话跟踪、过滤器Filter、监听器Listener等;第3篇为高级篇,内容包括JSTL标签库的使用、如何自定义标签、资源国际化、数据库概述、JDBC详解、XML概述等;第4篇为...

Global site tag (gtag.js) - Google Analytics