servlet 过滤器

来源:互联网 发布:淘宝捡漏是什么意思 编辑:程序博客网 时间:2024/06/06 00:03
简单介绍下servlet的过滤器,虽然标题是Jsp

    1.创建一个过滤器

    我们首先创建一个web工程,

    工程首页有一个连接

      <a href="<%=path %>/servlet/loginServlet?username=管理员&password=1">进入后台</a>

    这里,我们创建一个servlet(关于如何创建和访问servlet不是我们今天的重点)
    

    @Override
         protected void doPost(HttpServletRequest req, HttpServletResponse resp)
                 throws ServletException, IOException {
    
             String username = req.getParameter("username");
             String password = req.getParameter("password");
    
     }

    

    这里我们发现username会是乱码,因此我们需要手动为其设置编码

    req.setCharacterEncoding("GBK");

    这个没有问题,但是假设有N个servlet或则说有许多不同逻辑的请求,自然就需要很多的同样操作

    因此就需要一个字符的过滤器

    OK

    要实现过滤器,必须实现javax.servlet.Filter接口

    并重写doFilter方法

    先贴代码 在解释
    

      /**
      * 字符过滤器
      *
       */
     // 实现过滤器的方法 实现filter接口 重写doFilter方法
     public class EncodeFilter implements Filter {
    
          private String encode = null;
          private boolean ignore = false;// 过滤器开关
    
         public void destroy() {
             encode = null;
             ignore = false;
         }
    
         public void doFilter(ServletRequest request, ServletResponse response,
                 FilterChain chain) throws IOException, ServletException {
             if (!ignore) {
                 if (null == request.getCharacterEncoding()) {
                     request.setCharacterEncoding(encode);
    
                 }
             }
             chain.doFilter(request, response);
    
         }
    
         public void init(FilterConfig filterConfig) throws ServletException {
             String encode = filterConfig.getInitParameter("encode");
             String ignore = filterConfig.getInitParameter("ignore");
             if (this.encode == null)
                 this.encode = encode;
             if ("1".equals(ignore) || "yes".equals(ignore)) {
                 this.ignore = true;
             }
         }
    
     }

    
    

     <filter>
         <filter-name>encodeFilter</filter-name>
         <filter-class>com.lwx.filter.EncodeFilter</filter-class>
         <init-param>
             <param-name>encode</param-name>
             <param-value>GBK</param-value>
         </init-param>
         <init-param>
             <param-name>ignore</param-name>
             <param-value>false</param-value>
         </init-param>
     </filter>
     <filter-mapping>
         <filter-name>encodeFilter</filter-name>
         <url-pattern>/*</url-pattern>
     </filter-mapping>

    

    这里解释下

    <filter-mapping>中的<url-pattern>就是过滤器要过滤的对象/* 就是对所有的请求进行过滤
    当然这里还有一个过滤器的开关ignore 当ignore为true/1/yes的时候,则过滤器不起作用,还有一个就是过滤器要设置的编码格式的值

    java代码中,

    init方法是初始化过滤器的时候调用一次

    destroy 则不用解释了

    doFilter 则是需要我们去重写的

    OK 到此一个完整的字符过滤器就算结束,但是我们的话题还没有结束

    现在我有一个想法,那就是对非法用户(没有登录的用户和没有权限访问的用户)进行过滤

    二、登录过滤器
    我们知道,很多时候我们在影响用户请求的时候,都需要判断用户是否已经登录,或则他的session是否已经失效,如果是的话,则跳到登录页,等待重新登录后才可以继续下一步的操作
    OK
    假设现在我们有一个登录的页面

    代码如下

    1 <form action="<%=path %>/servlet/loginServlet?task=login" method="post">
    2         <div>用户名:<input type="text" name="username"></div>
    3         <div>密码:<input type="password" name="password"></div>
    4         <div><input type="submit" value="登录"></div>
    5     </form>

    

                if (task.equals("login")) {
                    if (null != username && username.trim().length() > 0
                            && username.equals("lwx")) {
                        if (null != password && password.trim().length() > 0
                                && password.equals("1")) {
                            User user = new User();
                            user.setUsername(username);
                            req.getSession().setAttribute("user", user);
                            resp.sendRedirect(req.getContextPath() + "/manager/");

                        }
                    }
                }

            

    

    后台的处理代码

    当用户名等于lwx并且密码为1的时候,我们将跳转到/manager/index.jsp

    假设现在用户知道了这个地址,就可以轻松的访问我们的页面了,因此在进去之前需要做过滤

    同时/servlet/loginServlet?task=login 这个请求又是不需要过滤的

    因此综上考虑 ,我们这样设计过滤器
  代 码  
     
    public class LoginFilter implements Filter{  
        String permitUrls[]=null;  
        boolean ignore=false;  
        String gotoUrl=null;  
          
        public void destroy() {  
             permitUrls=null;  
             ignore=false;  
             gotoUrl=null;  
              
        }  
     
        public void doFilter(ServletRequest request, ServletResponse response,  
                FilterChain chain) throws IOException, ServletException {  
            HttpServletRequest res=(HttpServletRequest) request;  
            HttpServletResponse resp=(HttpServletResponse)response;  
            System.out.println("登录过滤器");  
            if(!ignore){  
                    if(!isPermitUrl(request)){  
                        if(filterCurrUrl(request)){  
                            resp.sendRedirect(res.getContextPath()+gotoUrl);  
                            return ;  
                        }  
                    }  
                      
                  
            }  
            chain.doFilter(request, response);  
        }  
          
        public boolean isPermitUrl(ServletRequest request){  
            boolean isPermit=false;  
              
            if(permitUrls!=null&&permitUrls.length>0){  
                for (int i = 0; i < permitUrls.length; i++) {  
                    if(permitUrls[i].equals(currentUrl(request))){  
                        isPermit=true;  
                        break;  
                    }  
                }  
            }  
            return isPermit;  
        }  
          
        public boolean filterCurrUrl(ServletRequest request){  
              
            boolean filter=false;  
            HttpServletRequest res=(HttpServletRequest) request;  
            User user =(User) res.getSession().getAttribute("user");  
            if(null==user)  
                filter=true;  
              
            return filter;  
              
        }  
          
        //xx.jsp  
        // servlet/aaServlet?task=11&bb=yy  
              
        public String currentUrl(ServletRequest request){  
              
            HttpServletRequest res=(HttpServletRequest) request;  
            String task=request.getParameter("task");  
            String path=res.getContextPath();  
            String uri=res.getRequestURI();  
            if(task!=null){//uri格式 xx/ser  
                uri=uri.substring(path.length(), uri.length())+"?"+"task="+task;  
            }else{  
                uri=uri.substring(path.length(), uri.length());  
            }  
            System.out.println("当前请求地址:"+uri);  
            return uri;  
        }  
          
     
        public void init(FilterConfig filterConfig) throws ServletException {  
            String ignore =filterConfig.getInitParameter("ignore");  
            String permitUrls =filterConfig.getInitParameter("permitUrls");  
            String gotoUrl =filterConfig.getInitParameter("gotoUrl");  
              
             if ("1".equals(ignore) || "yes".equals(ignore)||"true".equals(ignore)) {  
                    this.ignore = true;  
                }  
             if(permitUrls!=null&&permitUrls.length()>0);  
                 this.permitUrls=permitUrls.split(",");  
                   
             this.gotoUrl=gotoUrl;      
        }  
          
          
     
    }  
     
  代 码  
  代 码  
     
    <filter>  
        <filter-name>loginFilter</filter-name>  
        <filter-class>com.lwx.filter.LoginFilter</filter-class>  
          
        <init-param>  
            <param-name>ignore</param-name>  
            <param-value>false</param-value>  
        </init-param>  
        <init-param>  
            <param-name>permitUrls</param-name>  
            <param-value>/,/servlet/loginServlet?task=login,/index.jsp,/login/login.jsp</param-value>  
        </init-param>  
        <init-param>  
            <param-name>gotoUrl</param-name>  
            <param-value>/login/login.jsp</param-value>  
        </init-param>  
    </filter>          
    <filter-mapping>  
        <filter-name>loginFilter</filter-name>  
        <url-pattern>/*</url-pattern>  
    </filter-mapping>  
     
    

 public class User {
     
     private String username;
     private String password;

 }

    

    OK,登录过滤器仍然全部的请求地址,

    permitUrls 用来告诉过滤器哪些请求是登录过滤器不需要过滤的,最简单的肯定是首页,和登录校验的地址

    gotoUrl 表示当过滤器接收到非法请求的时候,需要跳转的页面 这样的好处是假设下次需要修改跳转的页面 只要修改配置文件,而不需要重新编译代码


    三、权限过滤器

    感觉到这里,视乎是可以告一个段落了,其实不然。
    假设我们有一个一般的用户,他登录后请求的一个地址是管理员才可以访问的 那对于网站来说是非常不利的。因此权限的过滤器也是非常有必要的

    还是先上代码

    

     public class AuthorityFilter implements Filter{
         String permitUrls[]=null;
         boolean ignore=false;
         String gotoUrl=null;
         
         public void destroy() {
              permitUrls=null;
              ignore=false;
              gotoUrl=null;
             
         }
    
         public void doFilter(ServletRequest request, ServletResponse response,
                 FilterChain chain) throws IOException, ServletException {
             HttpServletRequest res=(HttpServletRequest) request;
             HttpServletResponse resp=(HttpServletResponse)response;
             System.out.println("权限过滤器");
             if(!ignore){
                     if(!isPermitUrl(request)){
                         if(filterCurrUrl(request)){
                             
                             resp.sendRedirect(res.getContextPath()+gotoUrl);
                             return ;
                         }
                     }
                     
                 
             }
             chain.doFilter(request, response);
         }
         
         public boolean isPermitUrl(ServletRequest request){
             boolean isPermit=false;
             
             if(permitUrls!=null&&permitUrls.length>0){
                 for (int i = 0; i < permitUrls.length; i++) {
                     if(permitUrls[i].equals(currentUrl(request))){
                         isPermit=true;
                         break;
                     }
                 }
             }
             return isPermit;
         }
         
         public boolean filterCurrUrl(ServletRequest request){
             
             boolean filter=true;
             HttpServletRequest res=(HttpServletRequest) request;
             User user =(User) res.getSession().getAttribute("user");
             //List authorities=user.getUserAuthorities();
             //遍历authorities判断是否是该用户拥有的权限 否则
             //这里我们假定用户用户访问/manager/user_list.jsp的权限
             String currentUrl=currentUrl( request);
             if("/servlet/loginServlet?task=userlist".equals(currentUrl))
                 filter=false;
             
             
             
             
             return filter;
             
         }
         
         //xx.jsp
         // servlet/aaServlet?task=11&bb=yy
             
         public String currentUrl(ServletRequest request){
             
             HttpServletRequest res=(HttpServletRequest) request;
             String task=request.getParameter("task");
         String path=res.getContextPath();
         String uri=res.getRequestURI();
         if(task!=null){//uri格式 xx/ser
             uri=uri.substring(path.length(), uri.length())+"?"+"task="+task;
         }else{
             uri=uri.substring(path.length(), uri.length());
         }
         System.out.println("当前请求地址:"+uri);
         return uri;
     }
     

     public void init(FilterConfig filterConfig) throws ServletException {
         String ignore =filterConfig.getInitParameter("ignore");
         String permitUrls =filterConfig.getInitParameter("permitUrls");
         String gotoUrl =filterConfig.getInitParameter("gotoUrl");
         
          if ("1".equals(ignore) || "yes".equals(ignore)||"true".equals(ignore)) {
                 this.ignore = true;
             }
          if(permitUrls!=null&&permitUrls.length()>0);
              this.permitUrls=permitUrls.split(",");
              
          this.gotoUrl=gotoUrl;    
     }
     
     
 }

    
    

 <filter>
     <filter-name>encodeFilter</filter-name>
     <filter-class>com.lwx.filter.EncodeFilter</filter-class>
     <init-param>
         <param-name>encode</param-name>
         <param-value>GBK</param-value>
     </init-param>
     <init-param>
         <param-name>ignore</param-name>
         <param-value>false</param-value>
     </init-param>
 </filter>
 <filter>
     <filter-name>authorityFilter</filter-name>
     <filter-class>com.lwx.filter.AuthorityFilter</filter-class>
     
     <init-param>
         <param-name>ignore</param-name>
         <param-value>false</param-value>
     </init-param>
     <init-param>
         <param-name>permitUrls</param-name>
         <!-- 事实上 权限过滤器时将是否已登录的功能剥离出来 为了说明区别特意加了一个/manager/public.jsp-->
         <param-value>/,/servlet/loginServlet?task=login,/index.jsp,/login/login.jsp,/manager/,/manager/public.jsp,/error/noAuthority.jsp,/manager/user_list.jsp</param-value>
     </init-param>
     <init-param>
         <param-name>gotoUrl</param-name>
         <param-value>/error/noAuthority.jsp</param-value>
     </init-param>
 </filter>    
 <filter>
     <filter-name>loginFilter</filter-name>
     <filter-class>com.lwx.filter.LoginFilter</filter-class>
     
     <init-param>
         <param-name>ignore</param-name>
         <param-value>false</param-value>
     </init-param>
     <init-param>
         <param-name>permitUrls</param-name>
         <param-value>/,/servlet/loginServlet?task=login,/index.jsp,/login/login.jsp</param-value>
     </init-param>
     <init-param>
         <param-name>gotoUrl</param-name>
         <param-value>/login/login.jsp</param-value>
     </init-param>
 </filter>        
 <filter-mapping>
     <filter-name>encodeFilter</filter-name>
     <url-pattern>/*</url-pattern>
 </filter-mapping>
 <filter-mapping>
     <filter-name>loginFilter</filter-name>
     <url-pattern>/*</url-pattern>
 </filter-mapping>
 <filter-mapping>
     <filter-name>authorityFilter</filter-name>
     <url-pattern>/*</url-pattern>
 </filter-mapping>
     

    

    这里之所以把三个过滤器的配置都贴出来,及时说明下过滤器的顺序跟

    <filter-mapping>在web.xml中的顺序有关


0 0