zoukankan      html  css  js  c++  java
  • 学习Filter

    http://www.cnblogs.com/jbelial/archive/2012/07/09/2582638.html

    Filter 介绍:

      它主要用于对用户请求进行预处理,也可以对HttpServletResponse 进行后处理。使用Filter 的完整流程:Filter 对用户请求进行预处理,接着将请求交给Servlet 进行处理并生成响应,最后Filter 再对服务器响应进行后处理。

      Filter 用处:

      > 在 HttpServletRequest 到达 Servlet 之前,拦截客户的 HttpServletRequest 。 

      > 根据需要检查 HttpServletRequest ,也可以修改HttpServletRequest 头和数据。

      > 在HttpServletResponse 到达客户端之前,拦截HttpServletResponse 。 

      > 根据需要检查 HttpServletResponse ,也可以修改HttpServletResponse头和数据。

      

      Filter 种类:

      > 用户授权的 Filter 

      > 日志 Filter 

      > 负责解码的 Filter 

      > Filter 可负责拦截多个请求或响应 

    创建一个Filter:

      1、创建Filter类

      必须实现javax.servlet.Filter接口,在该接口中定义了如下方法:

      1、void init(FilerConfig config):用于完成Filter的初始化。

      2、void destroy():用于Filter撤销前,完成某些资源的回收。

      3、void doFilter(ServletRequest request,ServletResponse response, FilterChain chain):实现过滤功能,该方法就是对每一个请求及功能增加的额外处理。

      

    复制代码
    package jbelial.Filter;
    
    import java.io.IOException;
    
    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletContext;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.http.HttpServletRequest;
    
    public class LogFilter implements Filter {
        
        //FilterConfig用于访问Filter的配置信息
        private FilterConfig config ;
        // 实现销毁
        public void destroy() {
            // TODO Auto-generated method stub
            this.config = null ; 
        }
    
        public void doFilter(ServletRequest request, ServletResponse response,
                FilterChain chain) throws IOException, ServletException {
            // TODO Auto-generated method stub
            //-----------------对用户请求执行预处理-----------------------
            ServletContext context = this.config.getServletContext() ; 
            long before = System.currentTimeMillis() ; 
            System.out.println("开始过滤。。。。");
            //将请求转换成HttpServletRequest 请求。
            HttpServletRequest hrequest = (HttpServletRequest)request ; 
            System.out.println("Filter 已经截获到用户的请求的地址:" +
                    hrequest.getServletPath());
            // Filter 只是链式处理,请求依然放行到目的地址
            chain.doFilter(request, response) ; 
            //---------------对服务器响应执行后处理-----------------------
            long after = System.currentTimeMillis() ; 
            System.out.println("过滤结束。。。。");
            System.out.println("请求被定位到"+hrequest.getRequestURI()+
                    " 所花时间:"+(after - before));
            
        }
        // 实现初始化
        public void init(FilterConfig config) throws ServletException {
            // TODO Auto-generated method stub
            this.config = config ; 
        }
    
    }
    复制代码

      实现该方法就可以实现对用户的请求进行预处理,也可以对服务器响应进行后处理——分界线为是否调用了chain.doFilter(request.response) 。

       上面的请求Filter 仅在日志中记录请求的URL,对所有的请求都执行 chain.doFilter(request,response) 方法,当Filter 对请求过滤后依然将请求发送到目的地址。如果需要检查权限,可以在Filter中根据用户请求 HttpSession,判断用户权限是否足够。如果权限不够,直接调用重定向即可。

      2、配置Filter

       > 配置 Filter 名。

       > 配置 Filter 拦截 URL 模式。

         1、通过Annotation 进行配置

          在Filter 类 中添加:

          @WebFilter(filterName= "log",urlPatterns = {"/*"})

          下面附上@WebFilter 支持的常用属性表

    属性 是否必须 说明
    asyncSupported F 指定该Filter是否支持异步操作模式。
    dispatcherTypes F

    指定该Filter仅对dispatchar模式的请求进行过滤。该属性支持ASYNC、ERROR、FORWARD、

    INCLUDE、REQUST这5个值的任意组合。默认为同时过滤5种模式的请求。

    displayName  F 指定该Filter的显示名  
    filterName      指定该Filter的名字
    initParams F 用于为该Filter配置参数
    servletNames F 该属性值可指定多个Servlet的名称,用于指定该Filter仅对这几个Servlet执行过滤
    urlPatterns F 指定该Filter所拦截的URL

         2、在web.xml 文件中配置:

    复制代码
     <filter>
         <filter-name>log</filter-name>
         <filter-class>jbelial.Filter.LogFilter</filter-class>
     </filter>
     <filter-mapping>
         <filter-name>log</filter-name>
         <url-pattern>/*</url-pattern>
     </filter-mapping>
    复制代码

      

       Filter 的 doFilter()方法里面多了一个FilterChain 的参数,通过该参数可以控制是否放行用户请求。在实际项目中, Filter 里 doFilter() 方法里的代码就是从多个Servlet 的service() 方法里面抽取的通用代码,通过使用Filter 可以实现更好的代码复用。

       如下面的代码: 

    复制代码
    @WebFilter(filterName="authority"
        , urlPatterns={"/*"}
        , initParams={
            @WebInitParam(name="encoding", value="GBK"),
            @WebInitParam(name="loginPage", value="/login.jsp"),
            @WebInitParam(name="proLogin", value="/proLogin.jsp")})
    public class AuthorityFilter implements Filter 
    {
        //FilterConfig可用于访问Filter的配置信息
        private FilterConfig config;
        //实现初始化方法
        public void init(FilterConfig config)
        {
            this.config = config; 
        }
        //实现销毁方法
        public void destroy()
        {
            this.config = null; 
        }
        //执行过滤的核心方法
        public void doFilter(ServletRequest request,
            ServletResponse response, FilterChain chain)
            throws IOException,ServletException
        {
            //获取该Filter的配置参数
            String encoding = config.getInitParameter("encoding");
            String loginPage = config.getInitParameter("loginPage");
            String proLogin = config.getInitParameter("proLogin");
            //设置request编码用的字符集
            request.setCharacterEncoding(encoding);
            HttpServletRequest requ = (HttpServletRequest)request;
            HttpSession session = requ.getSession(true);
            //获取客户请求的页面
            String requestPath = requ.getServletPath();
            //如果session范围的user为null,即表明没有登录
            //且用户请求的既不是登录页面,也不是处理登录的页面
            if( session.getAttribute("user") == null
                && !requestPath.endsWith(loginPage)
                && !requestPath.endsWith(proLogin))
            {
                //forward到登录页面
                request.setAttribute("tip" , "您还没有登录");
                request.getRequestDispatcher(loginPage)
                    .forward(request, response);
            }
            //"放行"请求
            else
            {
                chain.doFilter(request, response);
            }
        } 
    }
    复制代码

      如果用户没有登录,那么只能访问/login.jsp和/proLogin.jsp页面。  

      在 web.xml文件中配置该Filter: 

    复制代码
     <filter>
         <filter-name>authority</filter-name>
         <filter-class>jbelial.Filter.Authority</filter-class>
         <init-param>
             <param-name>encoding</param-name>
             <param-value>GBK</param-value>
         </init-param>
              <init-param>
             <param-name>loginPage</param-name>
             <param-value>/login.jsp</param-value>
         </init-param>
              <init-param>
             <param-name>proLogin</param-name>
             <param-value>/proLogin.jsp</param-value>
         </init-param>
     </filter>
     <filter-mapping>
         <filter-name>authority</filter-name>
         <url-pattern>/*</url-pattern>
     </filter-mapping>
    </web-app>
    复制代码
  • 相关阅读:
    jsp转向
    什么是 XDoclet?
    tomcat中的几点配置说明
    mysql5问题
    POJ 3734 Blocks
    POJ 2409 Let it Bead
    HDU 1171 Big Event in HDU
    POJ 3046 Ant Counting
    HDU 2082 找单词
    POJ 1286 Necklace of Beads
  • 原文地址:https://www.cnblogs.com/exe19/p/5391690.html
Copyright © 2011-2022 走看看