精华内容
下载资源
问答
  • Filter详解

    2016-06-09 17:24:55
    JAVA学习篇--javaweb之Filter详解 在DRP项目中,多次提到了Filter,它解决了字符集的统一设置以及统一控制简单WebCache,从中我们可以体会到,它给我们带来的好处不仅仅是减少代码量这么简单,它的...
    JAVA学习篇--javaweb之Filter详解


    DRP项目中,多次提到了Filter,它解决了字符集的统一设置以及统一控制简单WebCache,从中我们可以体会到,它给我们带来的好处不仅仅是减少代码量这么简单,它的出现避免了我们每个页面重复的编写相同的代码,减少了我们的工作量,而且给维护带来了极大的便利,那么它是如何实现统一管理的呢?既然它能统一管理某些重复的操作,那么它和AOP有什么关系呢?

     

    Filter简介

     

    ServletAPI中提供了一个Filter接口,开发web应用时,如果编写的Java类实现了这个接口,则把这个java类称之为过滤器Filter。

    通过Filter技术,开发人员可以实现用户在访问某个目标资源之前,对访问的请求和响应进行拦截。简单说,就是可以实现web容器对某资源的访问前截获进行相关的处理,还可以在某资源向web容器返回响应前进行截获进行处理。

     

    下图是filter调用关系的UML:


                 


    一个filter必须实现javax.servlet.Filter。

    三个方法

    1. voidsetFilterConfig(FilterConfig config) //设置filter 的配置对象;

    2. FilterConfiggetFilterConfig() //返回filter的配置对象;

    3. voiddoFilter(ServletRequest req,ServletResponse res,FilterChain chain) //执行filter的工作

     

    Filter实现拦截的原理

     

    Filter接口中有一个doFilter方法,当开发人员编写好Filter类实现doFilter方法,并配置对哪个web资源进行拦截后,WEB服务器每次在调用web资源的service方法之前(服务器内部对资源的访问机制决定的),都会先调用一下filter的doFilter方法。

     

    应用举例:

     

    批量设置请求编码


    [java] view plain copy
     print?在CODE上查看代码片派生到我的代码片
    1. public class EncodingFilter implements Filter {    
    2.     
    3.     private String encoding = null;    
    4.     
    5.     public void destroy() {    
    6.         encoding = null;    
    7.     }    
    8.     
    9.     public void doFilter(ServletRequest request, ServletResponse response,    
    10.             FilterChain chain) throws IOException, ServletException {    
    11.         String encoding = getEncoding();    
    12.         if (encoding == null){    
    13.             encoding = "gb2312";    
    14.         }    
    15.         request.setCharacterEncoding(encoding);// 在请求里设置上指定的编码    
    16.         chain.doFilter(request, response);  //通过控制对chain.doFilter的方法的调用,来决定是否需要访问目标资源  
    17.     }    
    18.     
    19.     public void init(FilterConfig filterConfig) throws ServletException {    
    20.         this.encoding = filterConfig.getInitParameter("encoding");    
    21.     }    
    22.     
    23.     private String getEncoding() {    
    24.         return this.encoding;    
    25.     }    
    26.     
    27. }    

    xml配置代码


    [html] view plain copy
     print?在CODE上查看代码片派生到我的代码片
    1. <filter>    
    2.     <filter-name>EncodingFilter</filter-name>    
    3.     <filter-class>com.logcd.filter.EncodingFilter</filter-class>    
    4.     <init-param>    
    5.        <param-name>encoding</param-name>    
    6.        <param-value>gb2312</param-value>    
    7.     </init-param>    
    8. </filter>    
    9.     
    10. <filter-mapping>    
    11.    <filter-name>EncodingFilter</filter-name>    
    12.    <url-pattern>/*</url-pattern>    
    13. </filter-mapping>    

    如上的代码完成的功能为,无论进入那个页面,都要先执行EncodingFilter类的dofilter方法设置字符集

     

    其中,doFilter()方法类似于Servlet接口的service()方法。当客户端请求目标资源的时候,容器就会调用与这个目标资源相关联的过滤器的doFilter()方法。

    参数 request, response 为web 容器或 Filter 链的上一个 Filter 传递过来的请求和相应对象;参数 chain 代表当前 Filter 链的对象。

     

    对于FilterChain接口,代表当前Filter链的对象。由容器实现,容器将其实例作为参数传入过滤器对象的doFilter()方法中。

    过滤器对象使用FilterChain对象调用过滤器链中的下一个过滤器,或者目标Servlet 程序去处理,也可以直接向客户端返回响应信息,或者利用RequestDispatcher的forward()和include()方法,以及HttpServletResponse的sendRedirect()方法将请求转向到其他资源。

    这个方法的请求和响应参数的类型是 ServletRequest和ServletResponse,也就是说,过滤器的使用并不依赖于具体的协议。

     

    Filter生命周期

     

    和Servlet一样,Filter的创建和销毁也是由WEB服务器负责。


    与Servlet区别的是


    1>在应用启动的时候就进行装载Filter类而servlet是在请求时才创建(但filter与Servlet的load-on-startup配置效果相同)。

    2>容器创建好Filter对象实例后,调用init()方法。接着被Web容器保存进应用级的集合容器中去了等待着,用户访问资源。

    3>当用户访问的资源正好被Filter的url-pattern拦截时,容器会取出Filter类调用doFilter方法,下次或多次访问被拦截的资源时,Web容器会直接取出指定Filter对象实例调用doFilter方法(Filter对象常驻留Web容器了)。

    4>当应用服务被停止或重新装载了,则会执行Filter的destroy方法,Filter对象销毁。

     

    Filter工作原理(执行流程)

         

        当客户端发出Web资源的请求时,Web服务器根据应用程序配置文件设置的过滤规则进行检查,若客户请求满足过滤规则,则对客户请求/响应进行拦截,对请求头和请求数据进行检查或改动,并依次通过过滤器链,最后把请求/响应交给请求的Web资源处理。

        请求信息在过滤器链中可以被修改,也可以根据条件让请求不发往资源处理器,并直接向客户机发回一个响应。当资源处理器完成了对资源的处理后,响应信息将逐级逆向返回。同样在这个过程中,用户可以修改响应信息,从而完成一定的任务。

        过滤链的好处是,执行过程中任何时候都可以打断,只要不执行chain.doFilter()就不会再执行后面的过滤器和请求的内容。


                    


    针对多个过滤器来说,例如,EncodingFilter负责设置编码,SecurityFilter负责控制权限,服务器会按照web.xml中过滤器定义的先后循序组装成一条链,然后一次执行其中的doFilter()方法,在实际使用时,就要特别注意过滤链的执行顺序问题,像EncodingFilter就一定要放在所有Filter之前,这样才能确保在使用请求中的数据前设置正确的编码。

     

    总结:

     

    对于filter的应用相信大家已经明白了,它主要的作用就是用户在访问某个目标资源之前,对访问的请求和响应进行拦截,做一些处理,然后再调用目标程序,这样做的好处是可以对一些公共的操作进行抽象,就拿设置字符集来说,如果不使用这种方式,我们每个页面都要写设置字符集的语句。不但麻烦而且维护困难,但是如果使用filter的话,只需要添加一个类,在xml中配置一下,如果不想使用了,将配置文件中的内容去除即可。

     

    其实这就是一种AOP(Aspect OrientedProgramming),面向切面编程。它的主要的意图是:将日志记录,性能统计,安全控制,事务处理,异常处理等代码从业务逻辑代码中划分出来,通过对这些行为的分离,我们希望可以将它们独立到非指导业务逻辑的方法中,进而改变这些行为的时候不影响业务逻辑的代码。

    对于设置字符集来说,它并非是业务逻辑的内容,对于这些内容的处理我们就可以提取出来,使用filter进行整体设置,这种方式相当于对类中的内容做进一步的抽象,使我们的系统更加灵活,更加能应对变化!

     

    解疑:

     

    由于上篇博客介绍的动态代理,就是一种符合AOP的一种体现,现在我们又说Filter也符合AOP,那么大家一定会有一个疑问,动态代理和Filter处理问题的区别在哪里呢?First既然都符合AOP思想,那么一定都可以进行统一处理(其实核心就是做进一步抽象)。那么区别呢?

     

    从表现形式上来说,两者确实很相似,同样可以在你写的jsp、servlet代码的前后加入其它的动作,但是两者是有本质区别的。

    1、 filter基于回调函数,我们需要实现的filter接口中doFilter方法就是回调函数,而动态代理则基于java本身的反射机制,如果对这种形式不了解,可以去看看动态代理实现过程,这是aop的基础。这是两者最本质的区别。

    2、 filter是依赖于servlet容器的,即只能在servlet容器中执行,很显然没有servlet容器就无法来回调doFilter方法。而动态代理与servlet容器无关。

    展开全文
  • Filter 详解

    2017-05-26 23:07:23
    过滤器详解

    一、简介

    (一)概述

    1、Filter,过滤器,用于在servlet之外对request 和response 进行修改。Filter 有一个 FilterChain 的概念,一个FilterChain 包括多个 Filter。客户端请求 request在抵达servlet 之前会经过 FilterChain 里面所有的 Filter,服务器响应 response 从servlet 抵达客户端浏览器之前也会经过 FilterChain 里面所有的 Filter 。过程如图所示:




    (二) Filter 的实现

    1、实现自定义的 Filter 需要满足一下条件:

    1)实现 javax.servlet.Filter 接口,实现其 init、doFilter、destroy 三个方法。

    2)实现在web.xml中的配置。


    2、javax.servlet.Filter 接口

    1) Filter 接口有三个方法:这三个方法反应了  Filter 的生命周期。

    ①、init:只会在 web 程序加载的时候调用,即启动如tomcat等服务器时调用。一般负责加载配置的参数。

    ②、destroy :web程序卸载的时候调用。一般负责关闭某些容器等。

    ③、doFilter:每次客户端请求都会调用一次。Filter 的所有工作基本都集中在该方法中进行。 

    [java] view plain copy
    1. package servlet.filter;  
    2.   
    3. import java.io.IOException;  
    4.   
    5. import javax.servlet.Filter;  
    6. import javax.servlet.FilterChain;  
    7. import javax.servlet.FilterConfig;  
    8. import javax.servlet.ServletException;  
    9. import javax.servlet.ServletRequest;  
    10. import javax.servlet.ServletResponse;  
    11. import javax.servlet.http.HttpServletRequest;  
    12.   
    13. import org.apache.log4j.Logger;  
    14. /** 
    15.  *  
    16.  * MyFilter.java 
    17.  * 
    18.  * @title 过滤器 
    19.  * @description 
    20.  * @author SAM-SHO  
    21.  * @Date 2014-9-25 
    22.  */  
    23. public class MyFilter implements Filter {  
    24.   
    25.     private Logger logger = Logger.getLogger(this.getClass());  
    26.       
    27.     public void destroy() {  
    28.   
    29.     }  
    30.   
    31.     public void doFilter(ServletRequest req, ServletResponse resp,  
    32.             FilterChain chain) throws IOException, ServletException {  
    33.           
    34.         HttpServletRequest request = (HttpServletRequest) req;  
    35.           
    36.         String contextPath = request.getContextPath();//上下文路径  
    37.         String servletPath = request.getServletPath();//得到访问的servlet或者jsp的路径  
    38.           
    39.         logger.debug("上下文路径:"+contextPath);  
    40.         logger.debug("访问的servlet或者jsp的路径 : "+servletPath);  
    41.                   
    42.         chain.doFilter(req, resp);  
    43.   
    44.     }  
    45.   
    46.     public void init(FilterConfig filterConfig) throws ServletException {  
    47.   
    48.         String name =  filterConfig.getInitParameter("name");  
    49.         logger.debug("获取过滤器的初始化参数: " + name);  
    50.     }  
    51.   
    52. }  


    3、 配置 Filter:每个过滤器需要配置在web.xml中才能生效,一个Filter需要配置<filter> 和 <filter-mapping>标签。

    1)<filter>  :配置 Filter 名称,实现类以及初始化参数。可以同时配置多个初始化参数。

    2)<filter-mapping> :配置什么规则下使用这个Filter 。

    ①、<url-pattern> :配置url的规则,可以配置多个,也可以使用通配符(*)。例如 /jsp/* 适用于本ContextPath下以“/jsp/ ”开头的所有servlet路径, *.do 适用于所有以“ .do”结尾的servlet路径。


    ②、<dispatcher> :配置到达servlet的方式,可以同时配置多个。有四种取值:REQUEST、FORWARD、ERROR、INCLUDE。如果没有配置,则默认为REQUEST。它们的区别是:

    REQUEST :表示仅当直接请求servlet时才生效。

    FORWARD :表示仅当某servlet通过forward转发到该servlet时才生效。

    INCLUDE :Jsp中可以通过<jsp:include/>请求某servlet, 只有这种情况才有效。

    ERROR :Jsp中可以通过<%@page errorPage="error.jsp" %>指定错误处理页面,仅在这种情况下才生效。


    ③、<url-pattern>和<dispatcher> 是且的关系,只有满足<url-pattern>的条件,且满足<dispatcher>的条件,该Filter 才能生效。

    [html] view plain copy
    1. <!-- 过滤器配置 -->  
    2.     <filter>  
    3.         <filter-name>MyFilter</filter-name>  
    4.         <filter-class>servlet.filter.MyFilter</filter-class>  
    5.         <init-param>  
    6.             <param-name>name</param-name>  
    7.             <param-value>Sam-Sho</param-value>  
    8.         </init-param>  
    9.     </filter>  
    10.     <filter-mapping>  
    11.         <filter-name>MyFilter</filter-name>  
    12.         <url-pattern>/jsp/*</url-pattern>  
    13.         <url-pattern>*.do</url-pattern>  
    14.   
    15.         <dispatcher>REQUEST</dispatcher>  
    16.         <dispatcher>FORWARD</dispatcher>  
    17.     </filter-mapping>  


    3)总结:一个Web程序可以配置多个Filter ,访问有先后顺序,<filter-mapping> 配置在前面的Filter 执行要早于配置在后面的Filter 。


    二、常用 Filter 

    (一)字符编码的 Filter 

    1、字符编码的 Filter 几乎每个项目都会用到。代码如下:

    [java] view plain copy
    1. package servlet.filter;  
    2.   
    3. import java.io.IOException;  
    4.   
    5. import javax.servlet.Filter;  
    6. import javax.servlet.FilterChain;  
    7. import javax.servlet.FilterConfig;  
    8. import javax.servlet.ServletException;  
    9. import javax.servlet.ServletRequest;  
    10. import javax.servlet.ServletResponse;  
    11.   
    12. /** 
    13.  *  
    14.  * CharacterEncodingFilter.java 
    15.  *  
    16.  * @title 编码过滤器 
    17.  * @description 
    18.  * @author SAM-SHO 
    19.  * @Date 2014-10-12 
    20.  */  
    21. public class CharacterEncodingFilter implements Filter {  
    22.   
    23.     private String characterEncoding;  
    24.     private boolean enabled;//是否启用  
    25.   
    26.     public void init(FilterConfig config) throws ServletException {  
    27.   
    28.         // 获取配置好的参数,  
    29.         characterEncoding = config.getInitParameter("characterEncoding");//配置好的字符编码  
    30.         enabled = "true".equalsIgnoreCase(config.getInitParameter("enabled"));//是否启用  
    31.     }  
    32.   
    33.     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {  
    34.   
    35.         //设置字符编码  
    36.         if (enabled && characterEncoding != null) {  
    37.             request.setCharacterEncoding(characterEncoding);  
    38.             response.setCharacterEncoding(characterEncoding);  
    39.         }  
    40.   
    41.         chain.doFilter(request, response);//调用下一个过滤器  
    42.     }  
    43.   
    44.     public void destroy() {  
    45.         characterEncoding = null;//注销的时候,设为空  
    46.     }  
    47. }  

    2、web.xml 配置如下:

    [java] view plain copy
    1. <!-- 编码过滤器 -->  
    2. <filter>  
    3.     <filter-name>CharacterEncodingFilter</filter-name>  
    4.     <filter-class>servlet.filter.CharacterEncodingFilter</filter-class>  
    5.     <init-param>  
    6.         <param-name>characterEncoding</param-name>  
    7.         <param-value>UTF-8</param-value>  
    8.     </init-param>  
    9.     <init-param>  
    10.         <param-name>enabled</param-name>  
    11.         <param-value>true</param-value>  
    12.     </init-param>  
    13. </filter>  
    14. <filter-mapping>  
    15.     <filter-name>CharacterEncodingFilter</filter-name>  
    16.     <url-pattern>/*</url-pattern>  
    17. </filter-mapping>  


    (二)防盗链 Filter 

    1、防盗链需要使用到请求头 Referer ,该 Filter  的配置仅对 /images/ 和 /upload/images/ 下面的所有资源有效。代码如下:

    [java] view plain copy
    1. package servlet.filter;  
    2.   
    3. import java.io.IOException;  
    4.   
    5. import javax.servlet.Filter;  
    6. import javax.servlet.FilterChain;  
    7. import javax.servlet.FilterConfig;  
    8. import javax.servlet.ServletException;  
    9. import javax.servlet.ServletRequest;  
    10. import javax.servlet.ServletResponse;  
    11. import javax.servlet.http.HttpServletRequest;  
    12. import javax.servlet.http.HttpServletResponse;  
    13.   
    14. /** 
    15.  *  
    16.  * RefererFilter.java 
    17.  *  
    18.  * @title 责任链过滤器 
    19.  * @description 
    20.  * @author SAM-SHO 
    21.  * @Date 2014-12-9 
    22.  */  
    23. public class RefererFilter implements Filter {  
    24.   
    25.     public void init(FilterConfig config) throws ServletException {  
    26.     }  
    27.   
    28.     public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {  
    29.   
    30.         // 必须的  
    31.         HttpServletRequest request = (HttpServletRequest) req;  
    32.         HttpServletResponse response = (HttpServletResponse) res;  
    33.   
    34.         // 禁止缓存  
    35.         response.setHeader("Cache-Control""no-store");  
    36.         response.setHeader("Pragrma""no-cache");  
    37.         response.setDateHeader("Expires"0);  
    38.   
    39.         // 链接来源地址,通过获取请求头 referer 得到  
    40.         String referer = request.getHeader("referer");  
    41.         System.out.println("获取的来源--->: " + referer);  
    42.   
    43.         if (referer == null || !referer.contains(request.getServerName())) {//本站点访问,则有效  
    44.   
    45.             /** 
    46.              * 如果 链接地址来自其他网站,则返回错误图片 
    47.              */  
    48.             request.getRequestDispatcher("/error.gif").forward(request, response);  
    49.   
    50.         } else {  
    51.   
    52.             /** 
    53.              * 图片正常显示 
    54.              */  
    55.             chain.doFilter(request, response);  
    56.         }  
    57.   
    58.     }  
    59.   
    60.     public void destroy() {  
    61.     }  
    62. }  


    2、配置如下:

    [java] view plain copy
    1. <!--责任链过滤器  -->  
    2. <filter>  
    3.     <filter-name>RefererFilter</filter-name>  
    4.     <filter-class>servlet.filter.RefererFilter</filter-class>  
    5. </filter>  
    6. <filter-mapping>  
    7.     <filter-name>RefererFilter</filter-name>  
    8.     <url-pattern>/images/*</url-pattern>  
    9.     <url-pattern>/upload/images/*</url-pattern>  
    10. </filter-mapping>  


    (三)权限校验 Filter 

    1、为了方便,权限配置在文件中:

    [java] view plain copy
    1. package servlet.filter;  
    2.   
    3. import java.io.FileInputStream;  
    4. import java.io.IOException;  
    5. import java.util.Properties;  
    6.   
    7. import javax.servlet.Filter;  
    8. import javax.servlet.FilterChain;  
    9. import javax.servlet.FilterConfig;  
    10. import javax.servlet.ServletException;  
    11. import javax.servlet.ServletRequest;  
    12. import javax.servlet.ServletResponse;  
    13. import javax.servlet.http.HttpServletRequest;  
    14.   
    15.   
    16. public class PrivilegeFilter implements Filter {  
    17.   
    18.     private Properties pp = new Properties();//读取配置文件  
    19.   
    20.     public void init(FilterConfig config) throws ServletException {  
    21.   
    22.         // 从 初始化参数 中获取权 限配置文件 的位置  
    23.         String file = config.getInitParameter("file");  
    24.         String realPath = config.getServletContext().getRealPath(file);  
    25.         try {  
    26.             pp.load(new FileInputStream(realPath));  
    27.         } catch (Exception e) {  
    28.             config.getServletContext().log("读取权限控制文件失败。", e);  
    29.         }  
    30.     }  
    31.   
    32.     public void doFilter(ServletRequest req, ServletResponse res,  
    33.             FilterChain chain) throws IOException, ServletException {  
    34.   
    35.         HttpServletRequest request = (HttpServletRequest) req;  
    36.   
    37.         // 获取访问的路径,例如:admin.jsp  
    38.         String requestURI = request.getRequestURI().replace(  
    39.                 request.getContextPath() + "/""");  
    40.   
    41.         // 获取 action 参数,例如:add  
    42.         String action = req.getParameter("action");  
    43.         action = action == null ? "" : action;  
    44.   
    45.         // 拼接成 URI。例如:log.do?action=list  
    46.         String uri = requestURI + "?action=" + action;  
    47.   
    48.         // 从 session 中获取用户权限角色。  
    49.         String role = (String) request.getSession(true).getAttribute("role");  
    50.         role = role == null ? "guest" : role;  
    51.   
    52.         boolean authentificated = false;  
    53.         // 开始检查该用户角色是否有权限访问 uri  
    54.         for (Object obj : pp.keySet()) {  
    55.             String key = ((String) obj);  
    56.             // 使用正则表达式验证 需要将 ? . 替换一下,并将通配符 * 处理一下  
    57.             if (uri.matches(key.replace("?""\\?").replace(".""\\.")  
    58.                     .replace("*"".*"))) {  
    59.                 // 如果 role 匹配  
    60.                 if (role.equals(pp.get(key))) {  
    61.                     authentificated = true;  
    62.                     break;  
    63.                 }  
    64.             }  
    65.         }  
    66.         if (!authentificated) {  
    67.             System.out.println("您无权访问该页面。请以合适的身份登陆后查看。");  
    68.         }  
    69.         // 继续运行  
    70.         chain.doFilter(req, res);  
    71.     }  
    72.   
    73.     public void destroy() {  
    74.         pp = null;  
    75.     }  
    76. }  

    2、web.xml配置如下:

    [html] view plain copy
    1. <!-- 权限过滤器 -->  
    2. <filter>  
    3.     <filter-name>privilegeFilter</filter-name>  
    4.     <filter-class>  
    5.         servlet.filter.PrivilegeFilter  
    6.     </filter-class>  
    7.     <init-param>  
    8.         <param-name>file</param-name>  
    9.         <param-value>/WEB-INF/classes/privilege.properties</param-value>  
    10.     </init-param>  
    11. </filter>  
    12. <filter-mapping>  
    13.     <filter-name>privilegeFilter</filter-name>  
    14.     <url-pattern>*.do</url-pattern>  
    15. </filter-mapping>  

    3、权限配置如下:

    [html] view plain copy
    1. # Privilege Settings  
    2.   
    3. admin.do?action\=*      =   administrator  
    4. log.do?action\=*        =   administrator  
    5.   
    6. list.do?action\=add     =   member  
    7. list.do?action\=delete  =   member  
    8. list.do?action\=save    =   member  
    9.   
    10. list.do?action\=view    =   guest  
    11. list.do?action\=list    =   guest  

    (四)GZIP 压缩 Filter 

    1、使用servlet 的对响应内容进行压缩:

    [java] view plain copy
    1. private void GZipTest(HttpServletResponse response) throws IOException {  
    2.     //实现压缩  
    3.     String tDate = "准备被压缩的数据";  
    4.     System.out.println("压缩前的数据大小:  "+tDate.getBytes().length);  
    5.       
    6.     ByteArrayOutputStream bout = new ByteArrayOutputStream();  
    7.     GZIPOutputStream gout = new GZIPOutputStream(bout);  
    8.     gout.write(tDate.getBytes());  
    9.     gout.flush();  
    10.     gout.finish();  
    11.     gout.close();//写到字节数组流中  
    12.       
    13.     byte[] gzip = bout.toByteArray();//得到压缩后的数据  
    14.     System.out.println("压缩后的数据大小:  "+gzip.length);  
    15.       
    16.     // 通知浏览器数据采用压缩格式  
    17.     response.setHeader("Content-Encoding""gzip");//压缩格式  
    18.     response.setHeader("Content-Length",gzip.length+"" );//压缩数据的长度  
    19.     response.getOutputStream().write(gzip);  
    20. }  


    2、使用过滤器代码:

    1)GZIP 压缩的核心是 JDK 自带的压缩数据的类,GZIPOutputStream 。

    2)响应头:Content-Encoding 和 Content-Length 。

    3)GZipResponseWrapper 类为自定义的 Response 类,内部对输出的内容进行 GZIP 的压缩。


    3、代码如下:

    [java] view plain copy
    1. package servlet.filter.gzip;  
    2.   
    3. import java.io.IOException;  
    4.   
    5. import javax.servlet.Filter;  
    6. import javax.servlet.FilterChain;  
    7. import javax.servlet.FilterConfig;  
    8. import javax.servlet.ServletException;  
    9. import javax.servlet.ServletRequest;  
    10. import javax.servlet.ServletResponse;  
    11. import javax.servlet.http.HttpServletRequest;  
    12. import javax.servlet.http.HttpServletResponse;  
    13.   
    14. /** 
    15.  *  
    16.  * GZipFilter.java 
    17.  *  
    18.  * @title 压缩过滤器 
    19.  * @description 
    20.  * @author SAM-SHO 
    21.  * @Date 2014-12-9 
    22.  */  
    23. public class GZipFilter implements Filter {  
    24.   
    25.     public void destroy() {  
    26.     }  
    27.   
    28.     public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {  
    29.   
    30.         HttpServletRequest request = (HttpServletRequest) req;  
    31.         HttpServletResponse response = (HttpServletResponse) res;  
    32.   
    33.         //获取浏览器支持的压缩格式  
    34.         String acceptEncoding = request.getHeader("Accept-Encoding");  
    35.         System.out.println("Accept-Encoding: " + acceptEncoding);  
    36.   
    37.         if (acceptEncoding != null && acceptEncoding.toLowerCase().indexOf("gzip") != -1) {  
    38.   
    39.             // 如果客户浏览器支持 GZIP 格式, 则使用 GZIP 压缩数据  
    40.             GZipResponseWrapper gzipResponse = new GZipResponseWrapper(response);  
    41.             chain.doFilter(request, gzipResponse);  
    42.   
    43.             // 输出压缩数据  
    44.             gzipResponse.getOutputStream();  
    45.             gzipResponse.finishResponse();  
    46.   
    47.         } else {  
    48.             // 否则, 不压缩  
    49.             chain.doFilter(request, response);  
    50.         }  
    51.     }  
    52.   
    53.     public void init(FilterConfig arg0) throws ServletException {  
    54.     }  
    55. }  

    [java] view plain copy
    1. package servlet.filter.gzip;  
    2.   
    3. import java.io.IOException;  
    4. import java.io.OutputStreamWriter;  
    5. import java.io.PrintWriter;  
    6.   
    7. import javax.servlet.ServletOutputStream;  
    8. import javax.servlet.http.HttpServletResponse;  
    9. import javax.servlet.http.HttpServletResponseWrapper;  
    10.   
    11. /** 
    12.  *  
    13.  * GZipResponseWrapper.java 
    14.  * 
    15.  * @title 封装的Response ,不会真正输出到客户端 
    16.  * 继承 HttpServletResponseWrapper,其实现了 HttpServletResponse 接口 
    17.  * @description 
    18.  * @author SAM-SHO  
    19.  * @Date 2014-12-9 
    20.  */  
    21. public class GZipResponseWrapper extends HttpServletResponseWrapper {  
    22.   
    23.     // 默认的 response  
    24.     private HttpServletResponse response;  
    25.   
    26.     // 自定义的 outputStream, 执行close()的时候对数据压缩,并输出  
    27.     private GZipOutputStream gzipOutputStream;  
    28.   
    29.     // 自定义 printWriter,将内容输出到 GZipOutputStream 中  
    30.     private PrintWriter writer;  
    31.   
    32.     public GZipResponseWrapper(HttpServletResponse response) throws IOException {  
    33.         super(response);  
    34.         this.response = response;  
    35.     }  
    36.     @Override  
    37.     public ServletOutputStream getOutputStream() throws IOException {  
    38.         if (gzipOutputStream == null)  
    39.             gzipOutputStream = new GZipOutputStream(response);  
    40.         return gzipOutputStream;  
    41.     }  
    42.     @Override  
    43.     public PrintWriter getWriter() throws IOException {  
    44.         if (writer == null)  
    45.             writer = new PrintWriter(new OutputStreamWriter(  
    46.                     new GZipOutputStream(response), "UTF-8"));  
    47.         return writer;  
    48.     }  
    49.   
    50.     // 压缩后数据长度会发生变化 因此将该方法内容置空  
    51.     @Override  
    52.     public void setContentLength(int contentLength) {  
    53.     }  
    54.     @Override  
    55.     public void flushBuffer() throws IOException {  
    56.         gzipOutputStream.flush();  
    57.     }  
    58.   
    59.     public void finishResponse() throws IOException {  
    60.         if (gzipOutputStream != null)  
    61.             gzipOutputStream.close();  
    62.         if (writer != null)  
    63.             writer.close();  
    64.     }  
    65. }  

    [java] view plain copy
    1. package servlet.filter.gzip;  
    2.   
    3. import java.io.ByteArrayOutputStream;  
    4. import java.io.IOException;  
    5. import java.util.zip.GZIPOutputStream;  
    6.   
    7. import javax.servlet.ServletOutputStream;  
    8. import javax.servlet.http.HttpServletResponse;  
    9.   
    10. /** 
    11.  *  
    12.  * GZipOutputStream.java 
    13.  * 
    14.  * @title 自定义的压缩流,内部调用JDK自带的压缩流 
    15.  * @description 
    16.  * @author SAM-SHO  
    17.  * @Date 2014-12-9 
    18.  */  
    19. public class GZipOutputStream extends ServletOutputStream {  
    20.   
    21.     private HttpServletResponse response;  
    22.   
    23.     // JDK 自带的压缩数据的类  
    24.     private GZIPOutputStream gzipOutputStream;  
    25.   
    26.     // 将压缩后的数据存放到 ByteArrayOutputStream 对象中  
    27.     private ByteArrayOutputStream byteArrayOutputStream;  
    28.   
    29.     public GZipOutputStream(HttpServletResponse response) throws IOException {  
    30.         this.response = response;  
    31.         byteArrayOutputStream = new ByteArrayOutputStream();  
    32.         gzipOutputStream = new GZIPOutputStream(byteArrayOutputStream);  
    33.     }  
    34.     @Override  
    35.     public void write(int b) throws IOException {  
    36.         gzipOutputStream.write(b);  
    37.     }  
    38.     @Override  
    39.     public void close() throws IOException {  
    40.   
    41.         // 压缩完毕 一定要调用该方法  
    42.         gzipOutputStream.finish();  
    43.   
    44.         // 将压缩后的数据输出到客户端  
    45.         byte[] content = byteArrayOutputStream.toByteArray();  
    46.   
    47.         // 设定压缩方式为 GZIP, 客户端浏览器会自动将数据解压  
    48.         response.addHeader("Content-Encoding""gzip");  
    49.         response.addHeader("Content-Length", Integer.toString(content.length));  
    50.   
    51.         // 输出  
    52.         ServletOutputStream out = response.getOutputStream();  
    53.         out.write(content);  
    54.         out.close();  
    55.     }  
    56.   
    57.     @Override  
    58.     public void flush() throws IOException {  
    59.         gzipOutputStream.flush();  
    60.     }  
    61.     @Override  
    62.     public void write(byte[] b, int off, int len) throws IOException {  
    63.         gzipOutputStream.write(b, off, len);  
    64.     }  
    65.     @Override  
    66.     public void write(byte[] b) throws IOException {  
    67.         gzipOutputStream.write(b);  
    68.     }  
    69. }  
    [html] view plain copy
    1. <!-- 压缩过滤器 -->  
    2. <filter>  
    3.     <filter-name>gzipFilter</filter-name>  
    4.     <filter-class>servlet.filter.gzip.GZipFilter</filter-class>  
    5. </filter>  
    6. <filter-mapping>  
    7.     <filter-name>gzipFilter</filter-name>  
    8.     <url-pattern>/*</url-pattern>  
    9. </filter-mapping>  


    (四)文件上传 Filter 

    1、上传文件,修改<form> 标签的 enctype 设置为 “multipart/form-data” 。这样就可以通过获取请求头 Content-type 判断是否为文件上传。

    2、使用 commons-fileupload-1.2.1.jar 实现上传。

    [java] view plain copy
    1. package servlet.filter.upload;  
    2.   
    3. import java.io.IOException;  
    4.   
    5. import javax.servlet.Filter;  
    6. import javax.servlet.FilterChain;  
    7. import javax.servlet.FilterConfig;  
    8. import javax.servlet.ServletException;  
    9. import javax.servlet.ServletRequest;  
    10. import javax.servlet.ServletResponse;  
    11. import javax.servlet.http.HttpServletRequest;  
    12.   
    13. /** 
    14.  *  
    15.  * UploadFilter.java 
    16.  * 
    17.  * @title 文件上传 Filter  
    18.  * @description 
    19.  * @author SAM-SHO  
    20.  * @Date 2014-12-9 
    21.  */  
    22. public class UploadFilter implements Filter {  
    23.   
    24.     public void destroy() {  
    25.   
    26.     }  
    27.   
    28.     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {  
    29.   
    30.         UploadRequestWrapper uploadRequest = new UploadRequestWrapper((HttpServletRequest) request);  
    31.   
    32.         chain.doFilter(uploadRequest, response);  
    33.   
    34.     }  
    35.   
    36.     public void init(FilterConfig filterConfig) throws ServletException {  
    37.   
    38.     }  
    39.   
    40. }  

    [java] view plain copy
    1. package servlet.filter.upload;  
    2.   
    3. import java.io.File;  
    4. import java.io.FileOutputStream;  
    5. import java.io.OutputStream;  
    6. import java.util.HashMap;  
    7. import java.util.Iterator;  
    8. import java.util.List;  
    9. import java.util.Map;  
    10.   
    11. import javax.servlet.http.HttpServletRequest;  
    12. import javax.servlet.http.HttpServletRequestWrapper;  
    13.   
    14. import org.apache.commons.fileupload.DiskFileUpload;  
    15. import org.apache.commons.fileupload.FileItem;  
    16.   
    17. /** 
    18.  *  
    19.  * UploadRequestWrapper.java 
    20.  *  
    21.  * @title 文件上传自定义Request 
    22.  * @description 
    23.  * @author SAM-SHO 
    24.  * @Date 2014-12-9 
    25.  */  
    26. public class UploadRequestWrapper extends HttpServletRequestWrapper {  
    27.   
    28.     private static final String MULTIPART_HEADER = "Content-type";  
    29.   
    30.     // 是否是上传文件  
    31.     private boolean multipart;  
    32.   
    33.     // map,保存所有的域  
    34.     private Map<String, Object> params = new HashMap<String, Object>();  
    35.   
    36.     @SuppressWarnings("all")  
    37.     public UploadRequestWrapper(HttpServletRequest request) {  
    38.   
    39.         super(request);  
    40.   
    41.         // 判断是否为上传文件  
    42.         multipart = request.getHeader(MULTIPART_HEADER) != null   
    43.                     && request.getHeader(MULTIPART_HEADER).startsWith("multipart/form-data");  
    44.   
    45.         //是文件上传  
    46.         if (multipart) {  
    47.   
    48.             try {  
    49.                 // 使用apache的工具解析  
    50.                 DiskFileUpload upload = new DiskFileUpload();//代替 DiskFileUpload   
    51.                 upload.setHeaderEncoding("utf8");  
    52.   
    53.                 // 解析,获得所有的文本域与文件域  
    54.                 List<FileItem> fileItems = upload.parseRequest(request);  
    55.   
    56.                 for (Iterator<FileItem> it = fileItems.iterator(); it.hasNext();) {  
    57.   
    58.                     // 遍历  
    59.                     FileItem item = it.next();  
    60.                     if (item.isFormField()) {  
    61.   
    62.                         // 如果是文本域,直接放到map里  
    63.                         params.put(item.getFieldName(), item.getString("utf8"));  
    64.   
    65.                     } else {  
    66.   
    67.                         // 否则,为文件,先获取文件名称  
    68.                         String filename = item.getName().replace("\\", "/");  
    69.                         filename = filename.substring(filename.lastIndexOf("/") + 1);  
    70.   
    71.                         // 保存到系统临时文件夹中  
    72.                         File file = new File(System.getProperty("java.io.tmpdir"), filename);  
    73.   
    74.                         // 保存文件内容  
    75.                         OutputStream ous = new FileOutputStream(file);  
    76.                         ous.write(item.get());  
    77.                         ous.close();  
    78.   
    79.                         // 放到map中  
    80.                         params.put(item.getFieldName(), file);  
    81.                     }  
    82.                 }  
    83.   
    84.             } catch (Exception e) {  
    85.                 e.printStackTrace();  
    86.             }  
    87.         }  
    88.     }  
    89.   
    90.     @Override  
    91.     public Object getAttribute(String name) {  
    92.   
    93.         // 如果为上传文件,则从map中取值  
    94.         if (multipart && params.containsKey(name)) {  
    95.             return params.get(name);  
    96.         }  
    97.         return super.getAttribute(name);  
    98.     }  
    99.   
    100.     @Override  
    101.     public String getParameter(String name) {  
    102.   
    103.         // 如果为上传文件,则从map中取值  
    104.         if (multipart && params.containsKey(name)) {  
    105.             return params.get(name).toString();  
    106.         }  
    107.         return super.getParameter(name);  
    108.     }  
    109.   
    110.     public static void main(String[] args) {  
    111.   
    112.         System.out.println(System.getProperties().toString().replace(", ""\r\n"));  
    113.   
    114.     }  
    115.   
    116. }  

    [html] view plain copy
    1. <!--  文件上传 Filter -->  
    2. <filter>  
    3.     <filter-name>uploadFilter</filter-name>  
    4.     <filter-class>servlet.filter.upload.UploadFilter</filter-class>  
    5. </filter>  
    6. <filter-mapping>  
    7.     <filter-name>uploadFilter</filter-name>  
    8.     <url-pattern>/*</url-pattern>  
    9. </filter-mapping>  
    展开全文
  • filter详解

    2017-08-24 22:21:00
    使用Filter的完整流程:Filter对用户请求进行预处理,接着将请求交给Servlet进行处理并生成响应,最后Filter再对服务器响应进行后处理。 Filter功能 在HttpServletRequest到达 Servlet 之前,拦截客户的...
    使用Filter的完整流程:Filter对用户请求进行预处理,接着将请求交给Servlet进行处理并生成响应,最后Filter再对服务器响应进行后处理。


    Filter功能


    在HttpServletRequest到达 Servlet 之前,拦截客户的HttpServletRequest 。根据需要检查HttpServletRequest,也可以修改HttpServletRequest 头和数据。
    在HttpServletResponse到达客户端之前,拦截HttpServletResponse 。根据需要检查HttpServletResponse,也可以修改HttpServletResponse头和数据。


    如何借助Filter实现拦截功能


    Filter接口中有一个doFilter方法,当开发人员编写好Filter,并配置对哪个web资源进行拦截后,Web服务器每次在调用web资源的service方法之前,都会先调用一下filter的doFilter方法,因此,在该方法内编写代码可达到如下目的:


    调用目标资源之前,让一段代码执行。
    是否调用目标资源(即是否让用户访问web资源)。
    web服务器在调用doFilter方法时,会传递一个filterChain对象进来,filterChain对象是filter接口中最重要的一个对象,它也提供了一个doFilter方法,开发人员可以根据需求决定是否调用此方法,调用该方法,则web服务器就会调用web资源的service方法,即web资源就会被访问,否则web资源不会被访问。
    Filter开发两步走


    编写java类实现Filter接口,并实现其doFilter方法。
    在web.xml文件中对编写的filter类进行注册,并设置它所能拦截的资源。


    web.xml配置各节点介绍:


    <filter>指定一个过滤器。
    <filter-name>用于为过滤器指定一个名字,该元素的内容不能为空。
    <filter-class>元素用于指定过滤器的完整的限定类名。
    <init-param>元素用于为过滤器指定初始化参数,它的子元素<param-name>指定参数的名字,<param-value>指定参数的值。
    在过滤器中,可以使用FilterConfig接口对象来访问初始化参数。
    <filter-mapping>元素用于设置一个 Filter 所负责拦截的资源。一个Filter拦截的资源可通过两种方式来指定:Servlet 名称和资源访问的请求路径
    <filter-name>子元素用于设置filter的注册名称。该值必须是在<filter>元素中声明过的过滤器的名字
    <url-pattern>设置 filter 所拦截的请求路径(过滤器关联的URL样式)
    <servlet-name>指定过滤器所拦截的Servlet名称。
    <dispatcher>指定过滤器所拦截的资源被 Servlet 容器调用的方式,可以是REQUEST,INCLUDE,FORWARD和ERROR之一,默认REQUEST。用户可以设置多个<dispatcher>子元素用来指定 Filter 对资源的多种调用方式进行拦截。
    <dispatcher>子元素可以设置的值及其意义
    REQUEST:当用户直接访问页面时,Web容器将会调用过滤器。如果目标资源是通过RequestDispatcher的include()或forward()方法访问时,那么该过滤器就不会被调用。
    INCLUDE:如果目标资源是通过RequestDispatcher的include()方法访问时,那么该过滤器将被调用。除此之外,该过滤器不会被调用。
    FORWARD:如果目标资源是通过RequestDispatcher的forward()方法访问时,那么该过滤器将被调用,除此之外,该过滤器不会被调用。
    ERROR:如果目标资源是通过声明式异常处理机制调用时,那么该过滤器将被调用。除此之外,过滤器不会被调用。
    Filter链


    在一个web应用中,可以开发编写多个Filter,这些Filter组合起来称之为一个Filter链。


    web服务器根据Filter在web.xml文件中的注册顺序,决定先调用哪个Filter,当第一个Filter的doFilter方法被调用时,web服务器会创建一个代表Filter链的FilterChain对象传递给该方法。在doFilter方法中,开发人员如果调用了FilterChain对象的doFilter方法,则web服务器会检查FilterChain对象中是否还有filter,如果有,则调用第2个filter,如果没有,则调用目标资源。


    Filter的生命周期


    public void init(FilterConfig filterConfig) throws ServletException;//初始化
    和我们编写的Servlet程序一样,Filter的创建和销毁由WEB服务器负责。 web 应用程序启动时,web 服务器将创建Filter 的实例对象,并调用其init方法,读取web.xml配置,完成对象的初始化功能,从而为后续的用户请求作好拦截的准备工作(filter对象只会创建一次,init方法也只会执行一次)。开发人员通过init方法的参数,可获得代表当前filter配置信息的FilterConfig对象。


    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException;//拦截请求
    这个方法完成实际的过滤操作。当客户请求访问与过滤器关联的URL的时候,Servlet过滤器将先执行doFilter方法。FilterChain参数用于访问后续过滤器。


    public void destroy();//销毁
    Filter对象创建后会驻留在内存,当web应用移除或服务器停止时才销毁。在Web容器卸载 Filter 对象之前被调用。该方法在Filter的生命周期中仅执行一次。在这个方法中,可以释放过滤器使用的资源。
    FilterConfig接口


    用户在配置filter时,可以使用为filter配置一些初始化参数,当web容器实例化Filter对象,调用其init方法时,会把封装了filter初始化参数的filterConfig对象传递进来。因此开发人员在编写filter时,通过filterConfig对象的方法,就可获得以下内容:


    String getFilterName();//得到filter的名称。 
    String getInitParameter(String name);//返回在部署描述中指定名称的初始化参数的值。如果不存在返回null. 
    Enumeration getInitParameterNames();//返回过滤器的所有初始化参数的名字的枚举集合。 
    public ServletContext getServletContext();//返回Servlet上下文对象的引用。
    Filter使用案例


    使用Filter验证用户登录安全控制


    前段时间参与维护一个项目,用户退出系统后,再去地址栏访问历史,根据url,仍然能够进入系统响应页面。我去检查一下发现对请求未进行过滤验证用户登录。添加一个filter搞定问题!


    先在web.xml配置


    <filter>
        <filter-name>SessionFilter</filter-name>
        <filter-class>com.action.login.SessionFilter</filter-class>
        <init-param>
            <param-name>logonStrings</param-name><!-- 对登录页面不进行过滤 -->
            <param-value>/project/index.jsp;login.do</param-value>
        </init-param>
        <init-param>
            <param-name>includeStrings</param-name><!-- 只对指定过滤参数后缀进行过滤 -->
            <param-value>.do;.jsp</param-value>
        </init-param>
        <init-param>
            <param-name>redirectPath</param-name><!-- 未通过跳转到登录界面 -->
            <param-value>/index.jsp</param-value>
        </init-param>
        <init-param>
            <param-name>disabletestfilter</param-name><!-- Y:过滤无效 -->
            <param-value>N</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>SessionFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    接着编写FilterServlet


    package com.action.login;


    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.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpServletResponseWrapper;


    /**
     *    判断用户是否登录,未登录则退出系统
     */
    public class SessionFilter implements Filter {


        public FilterConfig config;


        public void destroy() {
            this.config = null;
        }


        public static boolean isContains(String container, String[] regx) {
            boolean result = false;


            for (int i = 0; i < regx.length; i++) {
                if (container.indexOf(regx[i]) != -1) {
                    return true;
                }
            }
            return result;
        }


        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            HttpServletRequest hrequest = (HttpServletRequest)request;
            HttpServletResponseWrapper wrapper = new HttpServletResponseWrapper((HttpServletResponse) response);


            String logonStrings = config.getInitParameter("logonStrings");        // 登录登陆页面
            String includeStrings = config.getInitParameter("includeStrings");    // 过滤资源后缀参数
            String redirectPath = hrequest.getContextPath() + config.getInitParameter("redirectPath");// 没有登陆转向页面
            String disabletestfilter = config.getInitParameter("disabletestfilter");// 过滤器是否有效


            if (disabletestfilter.toUpperCase().equals("Y")) {    // 过滤无效
                chain.doFilter(request, response);
                return;
            }
            String[] logonList = logonStrings.split(";");
            String[] includeList = includeStrings.split(";");


            if (!this.isContains(hrequest.getRequestURI(), includeList)) {// 只对指定过滤参数后缀进行过滤
                chain.doFilter(request, response);
                return;
            }


            if (this.isContains(hrequest.getRequestURI(), logonList)) {// 对登录页面不进行过滤
                chain.doFilter(request, response);
                return;
            }


            String user = ( String ) hrequest.getSession().getAttribute("useronly");//判断用户是否登录
            if (user == null) {
                wrapper.sendRedirect(redirectPath);
                return;
            }else {
                chain.doFilter(request, response);
                return;
            }
        }


        public void init(FilterConfig filterConfig) throws ServletException {
            config = filterConfig;
        }
    }
    这样既可完成对用户所有请求,均要经过这个Filter进行验证用户登录。


    防止中文乱码过滤器


    项目使用spring框架时。当前台JSP页面和Java代码中使用了不同的字符集进行编码的时候就会出现表单提交的数据或者上传/下载中文名称文件出现乱码的问题,那就可以使用这个过滤器。


    <filter>
        <filter-name>encoding</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name><!--用来指定一个具体的字符集-->
            <param-value>UTF-8</param-value>
        </init-param>
        <init-param>
            <param-name>forceEncoding</param-name><!--true:无论request是否指定了字符集,都是用encoding;false:如果request已指定一个字符集,则不使用encoding-->
            <param-value>false</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>encoding</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    展开全文
  • servlet filter 详解

    2014-12-02 20:21:54
    servlet filter 详解 servlet servlet filter 详解 Servlet Filtering 过滤器(filter)是Java类,可以改变请求(request)和响应(response)的头信息与内容信息。过滤器不同于其他Web组件的地方是它本身并不...
     

    servlet filter 详解


    Servlet Filtering

    servlet filter 详解

    过滤器(filter)是Java类,可以改变请求(request)和响应(response)的头信息与内容信息。过滤器不同于其他Web组件的地方是它本身并不创建响应(response),然而它可以依附在任何类型的Web资源上。过滤器截取请求(request),检查和改变request对象、response对象,并可以执行一些其他的任务。过滤器提供的主要功能是:

    • 实现日志功能

    • 实现用户定义的安全功能

    • 调试功能

    • 加密

    • 数据压缩

    • 改变发送给客户端的响应(response)

    过滤器截获对特定命名的一个资源和一组资源的请求(request),然后执行过滤器中的代码。对于特定的资源,可以指定按照一定顺序调用的一个和多个过滤器,这就组成了链(chain)。使用过滤器主要包括:

    • 编写过滤器类

    • 定制请求(request)和响应(response)

    • 为特定的Web资源指定过滤器链

    6.5.1.1. 编写过滤器类

    编写过滤器的API是javax.servlet包中Filter、FilterChain和FilterConfig接口中定义的一些方法。定义一个过滤器就是实现Filter接口。Filter接口中最主要的方法是doFilter()方法,它接收三个参数:request对象、response对象、filterchain对象。

    void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)

    这个方法能够执行的动作包括:

    • 检查请求(request)的头信息

    • 定制request对象,改变请求(request)的头信息或数据

    • 定制response对象,改变响应(response)的头信息或数据

    • 调用在过滤器链中的下一个实体。如果当前过滤器是链中的最后一个过滤器,那么下一个实体就是客户请求(request)的资源;否则,链中的下一个过滤器会被调用。通过chain对象的doFilter()方法调用下一个实体,并传递request对象和response对象作为参数。另外,也可以不调用doFilter()方法阻塞请求(request),这样,过滤器应该负责填充对客户的响应(response)。

      关于chain.doFilter(request,response)
      他的作用是将请求转发给过滤器链上下一个对象。这里的下一个指的是下一个filter,如果没有filter那就是你请求的资源。 一般filter都是一个链,web.xml 里面配置了几个就有几个。一个一个的连在一起 

      request -> filter1 -> filter2 ->filter3 -> .... -> request resource.


    • 检查响应的头信息

    • 抛出异常显示处理过程中的错误

    除了doFilter()方法,开发人员也必须实现init()和destroy()方法。当容器创建过滤器实例时调用init()方法,

    void init(FilterConfig filterConfig)

    可以从FilterConfig对象中获得初始化参数。

    在doFilter()方法中,过滤器可以从FilterConfig对象获得ServletContext对象,那么就可以访问存储在ServletContext中的属性对象。当过滤器完成特定的处理过程后,调用chain对象的doFilter()方法。例如


    展开全文
  • css filter详解

    2015-07-06 20:55:00
    css filter详解 filter 属性详解 属性 名称 类型 说明 grayscale 灰度 值为数值 取值范围从0到1的小数(包括0和1) sepia 褐色 值为数值 取值范围从0到1的小数(包括0和1) ...
  • 例如某个Filter中的init方法执行抛异常了 struts本身就是使用Filter来启动的,利用了Filter自启动的特性,所以一定要保证Filter中的init方法的代码正确,Filter不像Servlet需要用户访问的时才实例化,即使某个...
  • java web之Filter详解2012-10-20 0 个评论 作者:chenshufei2 收藏 我要投稿、概念:Filter也称之为过滤器,它是Servlet技术中比较激动人心的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如...
  • Vue filter详解

    2019-12-09 19:24:16
    Vue filter源码详解 1.解析表达式 以reportDate | DFormat('YYYY-MM-DD') | SDefault为例。 parseFilters 解析函数位于node_modules/vue/src/compiler/parser/filter-parser.js。主要作用是将表达式转换为可立即执行...
  • java web之Filter详解

    2019-09-27 02:36:17
    java web之Filter详解 2012-10-20 0 个评论 作者:chenshufei2 收藏 我要投稿 、概念: Filter也称之为过滤器,它是Servlet技术中比较激动人心的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源...
  • java web之Filter详解2012-10-20 0 个评论 作者:chenshufei2 收藏 我要投稿、概念:Filter也称之为过滤器,它是Servlet技术中比较激动人心的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如...
  • 海量数据处理之Bloom Filter详解
  • 大数据场景之Bloom Filter详解 注意:Bloom Filter 主要应用 查重方面 其他方面待研究 首先看一个问题,针对这样的问题可以看到常规的解决方案 详细讲解Bloom Filter,并对需要的参数,譬如选择需要的存储的...
  • Android_Intent和Intent_Filter详解
  • Servlet中的过滤器Filter详解 web.xml中元素执行的顺序listener->filter->struts拦截器->servlet。 1.过滤器的概念 Java中的Filter 并不是一个标准的Servlet ,它不能处理用户请求,...
  • ColorFilter详解 转自:http://blog.csdn.net/abcdef314159 http://blog.csdn.net/allen315410/article/details/45059989 ColorFilter主要用来处理颜色,这里将讲解它的三个子类,ColorMatrixColorFilter,  ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 5,651
精华内容 2,260
关键字:

filter详解