Filter過濾器與listener監聽器的簡單使用
Filter過濾器是一種對客戶端訪問的過濾技術,簡單來說就是我們瀏覽器訪問伺服器檔案時,如果設定了特定的過濾配置,則會先經過過濾器,然後再將請求放給伺服器去執行,最常見的就是我們過濾使用者是否登入的使用。
listener監聽器,見名得意,他就是起到一個監聽的作用,主要是用來監聽web應用的建立和銷燬,以及他們attribute的建立、移除和更新等。 當然也包括用來監聽session、request的生命週期以及他們attribute的動態。
一:Filter過濾器
這裡我們以過濾器驗證使用者是否登入為例,進行解釋。
首先完整的使用Filter我們需要在web.xml中配置filter的相關資訊,告訴伺服器我要過濾什麼請求還是所有請求都過濾。然後對映到過濾器的類檔案中。
<filter>
<filter-name>FirstFilter</filter-name>
<filter-class>FirstFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>FirstFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
這裡配置的是過濾所有請求,當然也可以針對有一個或者某一類請求進行過濾。例如*.mml那所有的.mml結尾的請求都會過濾到過濾器中去處理。
2. 然後新建FirstFilter類檔案,需要實現Filter介面,並重寫該介面的三個方法。
執行銷燬方法:destory()、
執行過濾操作的方法:doFilter()、
初始化方法:init()。
其中doFilter()方法使我們過濾器執行實際過濾過程的方法,我們的實際業務邏輯就是寫在這個方法裡面的。該方法中有三個引數。
init()方法是過濾器的初始化方法,他跟servlet的init方法不一樣,servlet需要配置自啟動才會隨著tomcat的啟動執行init方法。二Filter的init方法一定會隨著tomcat的啟動而執行該方法的。
在這裡我們通過該過濾器打印出一句話,來驗證當我們請求時,會執行過濾器操作。程式碼如下:
//攔截器與servlet的執行順序,當訪問一個servlet請求時,先對servlet進行例項化、初始化、進入過濾器,
//執行過濾器的過濾,過濾器放行之後,再執行servlet的service方法。
public class FirstFilter implements Filter {
@Override
public void destroy() {
}
//執行攔截的方法
@Override
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
String url = request.getRequestURI().toString();
System.out.printf("訪問了 %s%n",url);
request.setCharacterEncoding("UTF-8");
chain.doFilter(request, response);
}
//攔截器的init初始化方法一定會隨著tomcat的啟動而啟動,不需要配置
@Override
public void init(FilterConfig arg0) throws ServletException {
}
}
因為doFilter方法中的引數是servletRequest型別的,我們先把引數轉化成HttpServletRequest型別的,然後獲取到請求的URL,列印在控制檯。通過chain.doFilter(request,response)這個方法,放行該請求,他就可以訪問伺服器上的資源了。代表著過濾器完成了過濾。
此時我們啟動tomcat,請求一個地址,就會看到控制檯上列印了我們輸出的URL地址。
這就是簡單使用過濾器的過程,下面我們在doFilter方法中加入驗證登入的過濾邏輯。
3. 驗證使用者是否登入,我們的核心思想就是
使用者開啟瀏覽器訪問該網址(此時伺服器自動建立一個session物件),當用戶登入並驗證成功之後,會在session中建立一個key為login的值為"yes"的鍵值對,
然後如果使用者請求的是login.jsp或者login結尾的登入頁面,過濾器放行。否則就判斷session存在login的值是否為空,如果為空,說明使用者沒有登入過,就跳轉到登入頁面,如果不為空,則放行。程式碼如下:
先是login的servlet驗證:如果驗證成功,就session中存一個鍵值對。
public class Login extends HttpServlet {
public void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException {
if("root".equals(request.getParameter("userName")) && "root".equals(request.getParameter("password"))) {
request.getSession().setAttribute("user", request.getParameter("userName"));
response.sendRedirect("heroList");
}else {
response.sendRedirect("login.html");
}
}
}
然後是Filter過濾器的邏輯:
public class FirstFilter implements Filter {
//執行攔截的方法
@Override
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
String url = request.getRequestURI().toString();
System.out.printf("訪問了 %s%n",url);
request.setCharacterEncoding("UTF-8");
if(url.endsWith("login.html") || url.endsWith("login")) {
chain.doFilter(request, response);
return;
}
String isUser = (String)request.getSession().getAttribute("user");
if(null == isUser || "" == isUser) {
response.sendRedirect("login.html");
return;
}
chain.doFilter(request, response);
}
}
這樣設定完成之後,我們開啟瀏覽器,如果先訪問heroList請求,則過濾器沒有獲取到session中的值,會調到登入頁面,直到我們登入驗證通過了,session中才會存入值,才會通過過濾器的已經登入的驗證。
二:listener監聽器:
1. 首先也需要在web.xml中告訴伺服器設定了監聽類:
<listener>
<listener-class>listener.OnlineNumberListener</listener-class>
<listener-class>listener.RequestListener</listener-class>
<listener-class>listener.SessionListener</listener-class>
<listener-class>listener.SessionListenerAttrute</listener-class>
</listener>
2. 首先新建RequseListener用來監聽request的生命週期和attribute的動態。程式碼如下:如果建立了reques物件就會執行該類中的對應的方法(相當於發起一次請求,就會執行該方法,因為request物件是請求物件,每重新發起請求都會建立一個request),建立attribute也一樣。
package listener;
import javax.servlet.ServletRequestAttributeEvent;
import javax.servlet.ServletRequestAttributeListener;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
public class RequestListener implements ServletRequestListener, ServletRequestAttributeListener {
@Override
public void attributeAdded(ServletRequestAttributeEvent arg0) {
System.out.println("建立了attribute:");
System.out.println("name:"+arg0.getName());
System.out.println("value:"+arg0.getValue());
}
@Override
public void attributeRemoved(ServletRequestAttributeEvent arg0) {
syso:監聽attribute的移除
}
@Override
public void attributeReplaced(ServletRequestAttributeEvent arg0) {
syso:監聽attribute的替換
}
@Override
public void requestDestroyed(ServletRequestEvent arg0) {
syso:監聽request的銷燬
}
@Override
public void requestInitialized(ServletRequestEvent arg0) {
System.out.println("建立了Request");
}
}
3. 新建SessionListener、SessionListenerAttrute類監聽session和attribute的動態,因為session比較特殊,需要用兩個監聽器分別來監聽。程式碼如下:
public class SessionListener implements HttpSessionListener {
@Override
public void sessionCreated(HttpSessionEvent arg0) {
System.out.println("監聽到session建立:Id是"+arg0.getSession().getId());
}
@Override
public void sessionDestroyed(HttpSessionEvent arg0) {
}
}
public class SessionListenerAttrute implements HttpSessionAttributeListener {
@Override
public void attributeAdded(HttpSessionBindingEvent arg0) {
System.out.println("監聽到建立了session的attribute,是:"+arg0.getName()+arg0.getValue());
}
@Override
public void attributeRemoved(HttpSessionBindingEvent arg0) {
System.out.println("******************退出了登入***********************");
}
@Override
public void attributeReplaced(HttpSessionBindingEvent arg0) {
}
}
使用session的建立和銷燬可以模糊的統計線上人數,因為開啟瀏覽器訪問頁面,就會建立session,也就是一次會話,就相當於一個線上人數,可以用作粗略統計。
感謝閱讀!