簡單介紹下servlet的過濾器,雖然標題是Jsp
1.創建一個過濾器
我們首先創建一個web工程,
工程首頁有一個連接
<a href="<%=path %>/servlet/loginServlet?username=管理員&password=1">進入后台</a>
這里,我們創建一個servlet(關於如何創建和訪問servlet不是我們今天的重點)
1 @Override 2 protected void doPost(HttpServletRequest req, HttpServletResponse resp) 3 throws ServletException, IOException { 4 5 String username = req.getParameter("username"); 6 String password = req.getParameter("password"); 7 8 }
這里我們發現username會是亂碼,因此我們需要手動為其設置編碼
req.setCharacterEncoding("GBK");
這個沒有問題,但是假設有N個servlet或則說有許多不同邏輯的請求,自然就需要很多的同樣操作
因此就需要一個字符的過濾器
OK
要實現過濾器,必須實現javax.servlet.Filter接口
並重寫doFilter方法
先貼代碼 在解釋
1 /** 2 * 字符過濾器 3 * 4 */ 5 // 實現過濾器的方法 實現filter接口 重寫doFilter方法 6 public class EncodeFilter implements Filter { 7 8 private String encode = null; 9 private boolean ignore = false;// 過濾器開關 10 11 public void destroy() { 12 encode = null; 13 ignore = false; 14 } 15 16 public void doFilter(ServletRequest request, ServletResponse response, 17 FilterChain chain) throws IOException, ServletException { 18 if (!ignore) { 19 if (null == request.getCharacterEncoding()) { 20 request.setCharacterEncoding(encode); 21 22 } 23 } 24 chain.doFilter(request, response); 25 26 } 27 28 public void init(FilterConfig filterConfig) throws ServletException { 29 String encode = filterConfig.getInitParameter("encode"); 30 String ignore = filterConfig.getInitParameter("ignore"); 31 if (this.encode == null) 32 this.encode = encode; 33 if ("1".equals(ignore) || "yes".equals(ignore)) { 34 this.ignore = true; 35 } 36 } 37 38 }
1 <filter> 2 <filter-name>encodeFilter</filter-name> 3 <filter-class>com.lwx.filter.EncodeFilter</filter-class> 4 <init-param> 5 <param-name>encode</param-name> 6 <param-value>GBK</param-value> 7 </init-param> 8 <init-param> 9 <param-name>ignore</param-name> 10 <param-value>false</param-value> 11 </init-param> 12 </filter> 13 <filter-mapping> 14 <filter-name>encodeFilter</filter-name> 15 <url-pattern>/*</url-pattern> 16 </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 這個請求又是不需要過濾的
因此綜上考慮 ,我們這樣設計過濾器
1 public class LoginFilter implements Filter{ 2 String permitUrls[]=null; 3 boolean ignore=false; 4 String gotoUrl=null; 5 6 public void destroy() { 7 permitUrls=null; 8 ignore=false; 9 gotoUrl=null; 10 11 } 12 13 public void doFilter(ServletRequest request, ServletResponse response, 14 FilterChain chain) throws IOException, ServletException { 15 HttpServletRequest res=(HttpServletRequest) request; 16 HttpServletResponse resp=(HttpServletResponse)response; 17 System.out.println("登錄過濾器"); 18 if(!ignore){ 19 if(!isPermitUrl(request)){ 20 if(filterCurrUrl(request)){ 21 resp.sendRedirect(res.getContextPath()+gotoUrl); 22 return ; 23 } 24 } 25 26 27 } 28 chain.doFilter(request, response); 29 } 30 31 public boolean isPermitUrl(ServletRequest request){ 32 boolean isPermit=false; 33 34 if(permitUrls!=null&&permitUrls.length>0){ 35 for (int i = 0; i < permitUrls.length; i++) { 36 if(permitUrls[i].equals(currentUrl(request))){ 37 isPermit=true; 38 break; 39 } 40 } 41 } 42 return isPermit; 43 } 44 45 public boolean filterCurrUrl(ServletRequest request){ 46 47 boolean filter=false; 48 HttpServletRequest res=(HttpServletRequest) request; 49 User user =(User) res.getSession().getAttribute("user"); 50 if(null==user) 51 filter=true; 52 53 return filter; 54 55 } 56 57 //xx.jsp 58 // servlet/aaServlet?task=11&bb=yy 59 60 public String currentUrl(ServletRequest request){ 61 62 HttpServletRequest res=(HttpServletRequest) request; 63 String task=request.getParameter("task"); 64 String path=res.getContextPath(); 65 String uri=res.getRequestURI(); 66 if(task!=null){//uri格式 xx/ser 67 uri=uri.substring(path.length(), uri.length())+"?"+"task="+task; 68 }else{ 69 uri=uri.substring(path.length(), uri.length()); 70 } 71 System.out.println("當前請求地址:"+uri); 72 return uri; 73 } 74 75 76 public void init(FilterConfig filterConfig) throws ServletException { 77 String ignore =filterConfig.getInitParameter("ignore"); 78 String permitUrls =filterConfig.getInitParameter("permitUrls"); 79 String gotoUrl =filterConfig.getInitParameter("gotoUrl"); 80 81 if ("1".equals(ignore) || "yes".equals(ignore)||"true".equals(ignore)) { 82 this.ignore = true; 83 } 84 if(permitUrls!=null&&permitUrls.length()>0); 85 this.permitUrls=permitUrls.split(","); 86 87 this.gotoUrl=gotoUrl; 88 } 89 90 91 92 }
1 <filter> 2 <filter-name>loginFilter</filter-name> 3 <filter-class>com.lwx.filter.LoginFilter</filter-class> 4 5 <init-param> 6 <param-name>ignore</param-name> 7 <param-value>false</param-value> 8 </init-param> 9 <init-param> 10 <param-name>permitUrls</param-name> 11 <param-value>/,/servlet/loginServlet?task=login,/index.jsp,/login/login.jsp</param-value> 12 </init-param> 13 <init-param> 14 <param-name>gotoUrl</param-name> 15 <param-value>/login/login.jsp</param-value> 16 </init-param> 17 </filter> 18 <filter-mapping> 19 <filter-name>loginFilter</filter-name> 20 <url-pattern>/*</url-pattern> 21 </filter-mapping>
1 public class User { 2 3 private String username; 4 private String password; 5 6 }
OK,登錄過濾器仍然全部的請求地址,
permitUrls 用來告訴過濾器哪些請求是登錄過濾器不需要過濾的,最簡單的肯定是首頁,和登錄校驗的地址
gotoUrl 表示當過濾器接收到非法請求的時候,需要跳轉的頁面 這樣的好處是假設下次需要修改跳轉的頁面 只要修改配置文件,而不需要重新編譯代碼
三、權限過濾器
感覺到這里,視乎是可以告一個段落了,其實不然。
假設我們有一個一般的用戶,他登錄后請求的一個地址是管理員才可以訪問的 那對於網站來說是非常不利的。因此權限的過濾器也是非常有必要的
還是先上代碼
1 public class AuthorityFilter implements Filter{ 2 String permitUrls[]=null; 3 boolean ignore=false; 4 String gotoUrl=null; 5 6 public void destroy() { 7 permitUrls=null; 8 ignore=false; 9 gotoUrl=null; 10 11 } 12 13 public void doFilter(ServletRequest request, ServletResponse response, 14 FilterChain chain) throws IOException, ServletException { 15 HttpServletRequest res=(HttpServletRequest) request; 16 HttpServletResponse resp=(HttpServletResponse)response; 17 System.out.println("權限過濾器"); 18 if(!ignore){ 19 if(!isPermitUrl(request)){ 20 if(filterCurrUrl(request)){ 21 22 resp.sendRedirect(res.getContextPath()+gotoUrl); 23 return ; 24 } 25 } 26 27 28 } 29 chain.doFilter(request, response); 30 } 31 32 public boolean isPermitUrl(ServletRequest request){ 33 boolean isPermit=false; 34 35 if(permitUrls!=null&&permitUrls.length>0){ 36 for (int i = 0; i < permitUrls.length; i++) { 37 if(permitUrls[i].equals(currentUrl(request))){ 38 isPermit=true; 39 break; 40 } 41 } 42 } 43 return isPermit; 44 } 45 46 public boolean filterCurrUrl(ServletRequest request){ 47 48 boolean filter=true; 49 HttpServletRequest res=(HttpServletRequest) request; 50 User user =(User) res.getSession().getAttribute("user"); 51 //List authorities=user.getUserAuthorities(); 52 //遍歷authorities判斷是否是該用戶擁有的權限 否則 53 //這里我們假定用戶用戶訪問/manager/user_list.jsp的權限 54 String currentUrl=currentUrl( request); 55 if("/servlet/loginServlet?task=userlist".equals(currentUrl)) 56 filter=false; 57 58 59 60 61 return filter; 62 63 } 64 65 //xx.jsp 66 // servlet/aaServlet?task=11&bb=yy 67 68 public String currentUrl(ServletRequest request){ 69 70 HttpServletRequest res=(HttpServletRequest) request; 71 String task=request.getParameter("task"); 72 String path=res.getContextPath(); 73 String uri=res.getRequestURI(); 74 if(task!=null){//uri格式 xx/ser 75 uri=uri.substring(path.length(), uri.length())+"?"+"task="+task; 76 }else{ 77 uri=uri.substring(path.length(), uri.length()); 78 } 79 System.out.println("當前請求地址:"+uri); 80 return uri; 81 } 82 83 84 public void init(FilterConfig filterConfig) throws ServletException { 85 String ignore =filterConfig.getInitParameter("ignore"); 86 String permitUrls =filterConfig.getInitParameter("permitUrls"); 87 String gotoUrl =filterConfig.getInitParameter("gotoUrl"); 88 89 if ("1".equals(ignore) || "yes".equals(ignore)||"true".equals(ignore)) { 90 this.ignore = true; 91 } 92 if(permitUrls!=null&&permitUrls.length()>0); 93 this.permitUrls=permitUrls.split(","); 94 95 this.gotoUrl=gotoUrl; 96 } 97 98 99 }
1 <filter> 2 <filter-name>encodeFilter</filter-name> 3 <filter-class>com.lwx.filter.EncodeFilter</filter-class> 4 <init-param> 5 <param-name>encode</param-name> 6 <param-value>GBK</param-value> 7 </init-param> 8 <init-param> 9 <param-name>ignore</param-name> 10 <param-value>false</param-value> 11 </init-param> 12 </filter> 13 <filter> 14 <filter-name>authorityFilter</filter-name> 15 <filter-class>com.lwx.filter.AuthorityFilter</filter-class> 16 17 <init-param> 18 <param-name>ignore</param-name> 19 <param-value>false</param-value> 20 </init-param> 21 <init-param> 22 <param-name>permitUrls</param-name> 23 <!-- 事實上 權限過濾器時將是否已登錄的功能剝離出來 為了說明區別特意加了一個/manager/public.jsp--> 24 <param-value>/,/servlet/loginServlet?task=login,/index.jsp,/login/login.jsp,/manager/,/manager/public.jsp,/error/noAuthority.jsp,/manager/user_list.jsp</param-value> 25 </init-param> 26 <init-param> 27 <param-name>gotoUrl</param-name> 28 <param-value>/error/noAuthority.jsp</param-value> 29 </init-param> 30 </filter> 31 <filter> 32 <filter-name>loginFilter</filter-name> 33 <filter-class>com.lwx.filter.LoginFilter</filter-class> 34 35 <init-param> 36 <param-name>ignore</param-name> 37 <param-value>false</param-value> 38 </init-param> 39 <init-param> 40 <param-name>permitUrls</param-name> 41 <param-value>/,/servlet/loginServlet?task=login,/index.jsp,/login/login.jsp</param-value> 42 </init-param> 43 <init-param> 44 <param-name>gotoUrl</param-name> 45 <param-value>/login/login.jsp</param-value> 46 </init-param> 47 </filter> 48 <filter-mapping> 49 <filter-name>encodeFilter</filter-name> 50 <url-pattern>/*</url-pattern> 51 </filter-mapping> 52 <filter-mapping> 53 <filter-name>loginFilter</filter-name> 54 <url-pattern>/*</url-pattern> 55 </filter-mapping> 56 <filter-mapping> 57 <filter-name>authorityFilter</filter-name> 58 <url-pattern>/*</url-pattern> 59 </filter-mapping> 60
這里之所以把三個過濾器的配置都貼出來,及時說明下過濾器的順序跟
<filter-mapping>在web.xml中的順序有關
最后附上工程代碼 下載
結束
偶的android嘎嘎