经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » Java » 查看文章
Filter内容
来源:cnblogs  作者:考拉熊_12  时间:2018/11/9 21:05:57  对本文有异议

1.利用Filter来过滤的时候大都是Http请求和Http响应,在doFilter()方法中,参数类是ServletRequest和ServletResponse  ,使用的时候一般需要强制转换为HttpServletRequest和HttpServletResponse  。针对这个问题,可以仿照GenericServlet 的做法,来定义一个HttpFilter,用作所有Filter的父类。

HttpFilter.java

  1. package com.javaweb.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.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;

    public abstract class HttpFilter implements Filter {
        @Override
        public void destroy() { }
        /*
         * 原生的doFilter方法,在方法内部把ServletRequest和ServletResponse转为了HttpServletRequest和HttpServletResponse,
         * 并调用了doFilter(HttpServletRequest request,HttpServletResponse response,FilterChain filterchain)方法。
         * 若编写Filter的过滤方法不建议直接继承该方法,而建议继承doFilter(HttpServletRequest request,HttpServletResponse response,
         * FilterChain filterchain)方法。
         * */
        @Override
        public void doFilter(ServletRequest req, ServletResponse resp, FilterChain filterchain)
                throws IOException, ServletException {
            HttpServletRequest request=(HttpServletRequest) req;
            HttpServletResponse response=(HttpServletResponse) resp;
            doFilter(request,response,filterchain);
        }
        //抽象方法,为Http请求定制必须实现的方法。
        public abstract void doFilter(HttpServletRequest request,HttpServletResponse response,FilterChain filterchain) throws IOException, ServletException;
        private FilterConfig filterconfig;
        //不建议子类直接覆盖,若直接覆盖,将可能会导致filterConfig成员变量初始化失败。
        @Override
        public void init(FilterConfig filterconfig) throws ServletException {
            this.filterconfig =filterconfig;
            init();
        }
        //供子类继承的初始化方法,可以通过getFilterConfig()获取FilterConfig对象。
        public void init(){}
        //直接返回init(ServletConfig)的ServletConfig对象。
        public FilterConfig getFilterConfig(){
            return filterconfig;
        }
    }

2.理解多个Filter代码的执行顺序

示例代码:

index.html

  1. <body>
  2. <a href="http://localhost:8080/MyWebProject/jspTest/test.jsp">to test jsp page</a>
  3. </body>

test.jsp

  1. <body>
  2. <%
  3. System.out.println("5. Test page");
  4. %>
  5. </body>

过滤器拦截:

filterTest.java

  1. package com.javaweb.Filter;
  2.  
  3. import java.io.IOException;
  4. import javax.servlet.Filter;
  5. import javax.servlet.FilterChain;
  6. import javax.servlet.FilterConfig;
  7. import javax.servlet.ServletException;
  8. import javax.servlet.ServletRequest;
  9. import javax.servlet.ServletResponse;
  10.  
  11. public class filterTest implements Filter {
  12. @Override
  13. public void destroy() {
  14. System.out.println("destroy...");
  15. }
  16.  
  17. @Override
  18. public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
  19. throws IOException, ServletException {
  20. System.out.println("1. before filterTest's chain.doFilter...");
  21. chain.doFilter(request,response);
  22. System.out.println("2. after filterTest's chain.doFilter...");
  23. }
  24.  
  25. @Override
  26. public void init(FilterConfig filterConfig) throws ServletException {
  27. System.out.println("init...");
  28. }
  29.  
  30. }

secondFilter.java

  1. package com.javaweb.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. public class secondFilter implements Filter {
  13. @Override
  14. public void destroy() {
  15. System.out.println("secondFilter's destroy...");
  16.  
  17. }
  18.  
  19. @Override
  20. public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
  21. throws IOException, ServletException {
  22. System.out.println("3. before secondFilter's chain doFilter...");
  23. chain.doFilter(request,response);
  24. System.out.println("4. after secondFilter's chain doFilter...");
  25. }
  26.  
  27. @Override
  28. public void init(FilterConfig arg0) throws ServletException {
  29. System.out.println("secondFilter's init...");
  30.  
  31. }
  32.  
  33. }

在web.xml中进行配置:

  1. <filter>
  2. <filter-name>filterTest</filter-name>
  3. <filter-class>com.javaweb.Filter.filterTest</filter-class>
  4. </filter>
  5. <filter-mapping>
  6. <filter-name>filterTest</filter-name>
  7. <url-pattern>/jspTest/test.jsp</url-pattern>
  8. </filter-mapping>
  9. <filter>
  10. <filter-name>secondFilter</filter-name>
  11. <filter-class>com.javaweb.Filter.secondFilter</filter-class>
  12. </filter>
  13. <filter-mapping>
  14. <filter-name>secondFilter</filter-name>
  15. <url-pattern>/jspTest/test.jsp</url-pattern>
  16. </filter-mapping>

执行顺序:

index.html页面点击链接时去test.jsp页面,被第一个过滤器filterTest拦截,

①首先执行其中的doFilter()方法,执行方法体中的System.out.println("1. before filterTest's chain.doFilter...");

②之后chain.doFilter(request,response);将拦截传递给下一个过滤器secondFilter,执行其中的doFilter()方法,同样执行方法体中的System.out.println("3. before secondFilter's chain doFilter...");

③接着chain.doFilter(request,response);因为没有过滤器,所以将请求转发到test.jsp,执行<% System.out.println("5. Test page"); %>;

④接下来执行方法体中的System.out.println("4. after secondFilter's chain doFilter...");

⑤最后回到filterTest的doFilter()方法中,执行System.out.println("2. after filterTest's chain.doFilter...");

3.<dispatcher>

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

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

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

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

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

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

 

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号