初做網站需要登錄驗證,轉自 :http://blog.csdn.net/daguanjia11/article/details/48995789
Filter:
Filter是服務器端的組件,用來過濾web請求。當發生一個web請求時,web容器會先檢查請求的URL是否設置了Filter,如果設置了,則執行該Filter的doFilter方法。所有Filter都實現了javax.servlet.Filter接口,doFilter是定義在該接口中的最重要的方法。
最常見的使用過濾器的例子有:登錄訪問頁面驗證,錯誤日志記錄,編碼轉換等。
也可以對一個URL設置多個Filter,這些Filter會形成一個過濾鏈,對過濾鏈的處理其實是責任鏈模式。
登錄驗證示例代碼
今天我用一個驗證登錄例子,讓大家對Filter(過濾器)有一個初步的認識。本例包含一個index.jsp頁面,一個login.jsp頁面,一個LoginFilter。我在配置文件中指定將LoginFilter用於index.jsp,當用戶訪問index.jsp頁面時,如果未登錄,則重定向到login.jsp進行登錄。
新增一個index.jsp頁面
代碼如下:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <h1>歡迎訪問主頁</h1> </body> </html>
新增一個login.jsp頁面
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <h1>請登錄</h1> </body> </html>
新增一個LoginFilter類
新增一個LoginFilter類,實現javax.servlet.Filter接口,在doFilter方法中驗證session是否包含username屬性,如果不包含,則重定向到login.jsp中。代碼如下:
package com.zdk.test; 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; import javax.servlet.http.HttpSession; public class LoginFilter implements Filter { @Override public void destroy() { } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest httpRequest=(HttpServletRequest)request; HttpServletResponse httpResponse=(HttpServletResponse)response; HttpSession session=httpRequest.getSession(); if(session.getAttribute("username")!=null){ chain.doFilter(request, response); } else{ httpResponse.sendRedirect(httpRequest.getContextPath()+"/login.jsp"); } } @Override public void init(FilterConfig arg0) throws ServletException { } }
配置Filter
在web.xml中,將LoginFilter應用於index.jsp頁面
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <display-name>HelloWorld</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> <filter> <filter-name>loginFilter</filter-name> <filter-class>com.zdk.test.LoginFilter</filter-class> </filter> <filter-mapping> <filter-name>loginFilter</filter-name> <url-pattern>/index.jsp</url-pattern> </filter-mapping> </web-app>
然后,發布站點,啟動tomcat,在瀏覽器中輸入localhost:8080:{projectname}/index.jsp,將{projectname}換成你的web projet的項目名稱,頁面將會重定向到login.jsp中,因為在index.jsp頁面中我們讀取不到登錄信息。
將LoginFilter用於多個頁面
如果順利的話,到這里我們的LoginFilter已經能夠完成工作了。但是我們不可能只對一個頁面進行登錄驗證,也不可能對所有的頁面都進行登錄驗證,如何靈活地設置呢?
我們要修改登錄驗證的范圍,對除了login.jsp,page2.jsp以外的所有頁面都進行登錄驗證。首先,我們修改web.xml
<filter> <filter-name>loginFilter</filter-name> <filter-class>com.zdk.test.LoginFilter</filter-class> <init-param> <param-name>passUrl</param-name> <param-value>login.jsp;page2.jsp;</param-value> </init-param> </filter> <filter-mapping> <filter-name>loginFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
我們為loginFilter指定了一個passUrl的參數,然后將該過濾器的url-pattern設置為/*。這樣做的意思是,loginFilter將被用於所有請求,除了寫在passUrl中的。當然,忽略的邏輯需要我們自己實現。下面是修改好的LoginFilter類
package com.zdk.test; 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; import javax.servlet.http.HttpSession; public class LoginFilter implements Filter { @Override public void destroy() { } String passUrl = ""; @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest httpRequest = (HttpServletRequest) request; HttpServletResponse httpResponse = (HttpServletResponse) response; String[] strArray = passUrl.split(";"); for (String str : strArray) { if (str.equals("")) continue; if (httpRequest.getRequestURL().indexOf(str) >= 0) { chain.doFilter(request, response); return; } } HttpSession session = httpRequest.getSession(); if (session.getAttribute("username") != null) { chain.doFilter(request, response); } else { httpResponse.sendRedirect(httpRequest.getContextPath() + "/login.jsp"); } } @Override public void init(FilterConfig arg0) throws ServletException { passUrl = arg0.getInitParameter("passUrl"); } }
首先在init方法中讀取我們設置的passUrl,保存到變量中。如果當前請求的URL包含在了passURL中,則不對其進行登錄校驗。