zoukankan      html  css  js  c++  java
  • Filter内容

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

    HttpFilter.java

    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

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

    test.jsp

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

    过滤器拦截:

    filterTest.java

    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;
    
    public class filterTest implements Filter {
    	@Override
    	public void destroy() {
    		System.out.println("destroy...");
    	}
    
    	@Override
    	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
    			throws IOException, ServletException {
    		System.out.println("1. before filterTest's chain.doFilter...");
    		chain.doFilter(request,response);
    		System.out.println("2. after filterTest's chain.doFilter...");
    	}
    
    	@Override
    	public void init(FilterConfig filterConfig) throws ServletException {
    		System.out.println("init...");
    	}
    
    }
    

    secondFilter.java

    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;
    
    public class secondFilter implements Filter {
    	@Override
    	public void destroy() {
    		System.out.println("secondFilter's destroy...");
    
    	}
    
    	@Override
    	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
    			throws IOException, ServletException {
    	System.out.println("3. before secondFilter's chain doFilter...");
            chain.doFilter(request,response);
            System.out.println("4. after secondFilter's chain doFilter...");
    	}
    
    	@Override
    	public void init(FilterConfig arg0) throws ServletException {
    		System.out.println("secondFilter's init...");
    
    	}
    
    }
    

    在web.xml中进行配置:

      <filter>
        <filter-name>filterTest</filter-name>
        <filter-class>com.javaweb.Filter.filterTest</filter-class>
      </filter>
      <filter-mapping>
        <filter-name>filterTest</filter-name>
        <url-pattern>/jspTest/test.jsp</url-pattern>
      </filter-mapping>
      <filter>
        <filter-name>secondFilter</filter-name>
        <filter-class>com.javaweb.Filter.secondFilter</filter-class>
      </filter>
      <filter-mapping>
        <filter-name>secondFilter</filter-name>
        <url-pattern>/jspTest/test.jsp</url-pattern>
      </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:如果目标资源是通过声明式异常处理机制调用时,那么该过滤器将会被调用,除此之外,过滤器不会被调用。

  • 相关阅读:
    如何用Map对象创建Set对象
    SpringMVC如何接受POST请求中的json参数
    Eclipse启动的时候提示:Failed to load JavaHL Library.
    spring中的scope详解
    synchronized 与 Lock 的那点事
    (转)Lock和synchronized比较详解
    java事件机制
    linux查看内存占用情况
    Linux命令简写和全称
    人类未来思考
  • 原文地址:https://www.cnblogs.com/naihuangbao/p/9935739.html
Copyright © 2011-2022 走看看