servlet 過濾器

簡單介紹下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中的順序有關


發佈了173 篇原創文章 · 獲贊 9 · 訪問量 24萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章