Filter和Listener編程實踐

一诡右、實驗內(nèi)容

1、Filter的理解和應(yīng)用

實現(xiàn)一個禁止緩存的過濾器轻猖。

要求和提示:

(1)禁止瀏覽器緩存所有動態(tài)頁面帆吻;

(2)有3個http響應(yīng)頭字段可以禁止瀏覽器緩存當前頁面,它們在Servlet中的示例代碼如下咙边。

response.setDateHeader("Expires",-1);

response.setHeader("Cache-Control","no-cache");

response.setHeader("Pragma","no-cache");

(3)并不是所有的瀏覽器都能完全支持上面的3個響應(yīng)頭猜煮,因此最好是同時使用上面的3個響應(yīng)頭次员。

代碼如下:
ExampleFilter.java

package com.qst.chapter02;
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.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebFilter("/ExampleFilter")
public class ExampleFilter implements Filter {


    public ExampleFilter() {
        // TODO Auto-generated constructor stub
    }


    public void destroy() {
        // TODO Auto-generated method stub
    }

     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
              
            //HttpServletRequest req=(HttpServletRequest) request;  
            HttpServletResponse res=(HttpServletResponse) response;  
       
            res.setDateHeader("Expires",-1);
            res.setHeader("Cache-Control","no-cache");
            res.setHeader("Pragma","no-cache");
            chain.doFilter(request, response);
            
        }
    public void init(FilterConfig fConfig) throws ServletException {
        // TODO Auto-generated method stub
    }

}

xml配置

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0">
  <display-name>chapter02</display-name>

<filter>
    <filter-name>ExampleFilter</filter-name>
    <filter-class>com.qst.chapter02.ExampleFilter</filter-class>
  </filter>
  
  <filter-mapping>
    <filter-name>ExampleFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
</web-app>

驗證方法:打開一個瀏覽器(不能在編譯器自帶的瀏覽器中打開),在網(wǎng)頁中右鍵點審查元素王带,network中找到頁面淑蔚,如下圖

image.png

效果:
有過濾器
image.png

無過濾器
image.png

2、Filter的理解和應(yīng)用

設(shè)計一個簡單的IP地址過濾器愕撰,根據(jù)用戶的IP地址進行網(wǎng)站的訪問控制刹衫。例如:禁止IP地址處在192.168.2網(wǎng)段的用戶對網(wǎng)站的訪問。
思路:
用字符串模擬一個IP地址搞挣,通過過濾器带迟,觀察是否能打開網(wǎng)頁,網(wǎng)頁代碼隨便一個皆可。
代碼:
ExampleFilter.java

package com.qst.chapter02;
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.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.ws.Response;

@WebFilter("/ExampleFilter")
public class ExampleFilter implements Filter {

    private String ip;
    private String[] ips;
    public ExampleFilter() {
        // TODO Auto-generated constructor stub
    }


    public void destroy() {
        // TODO Auto-generated method stub
    }

     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
              
            HttpServletRequest req=(HttpServletRequest) request;  
            HttpServletResponse res=(HttpServletResponse) response;  
            //模擬IP地址
            String localip="192.168.2.50";
            //拆分字符,提取部分IP地址
            String localipnum=localip.substring(0,localip.lastIndexOf("."));
            if(localipnum.equals("192.168.2"))
            {
                response.getWriter().print("IP:"+localip);
                response.getWriter().print("error!");
            }
            else
            {
                chain.doFilter(request, response);
            }

            
        }
    public void init(FilterConfig fConfig) throws ServletException {
        // TODO Auto-generated method stub
    }

}

效果:
模擬地址192.168.2.50

image.png

模擬地址192.168.1.50(不是禁止的網(wǎng)段即可正常顯示)
image.png

3囱桨、Listener的理解和應(yīng)用

通過監(jiān)聽器記錄在線用戶的姓名仓犬,在頁面進行用戶姓名的顯示,同時實現(xiàn)對某個用戶的強制下線功能舍肠。
思路:
用監(jiān)聽器監(jiān)聽每一次會話的發(fā)起和結(jié)束搀继,然后將信息保存下來并顯示,注意翠语,因為每一次的session會話都是要由不同的客戶端發(fā)起的叽躯,所以你在運行的時候是無法在同一個瀏覽器測試的,請在多個瀏覽器打開網(wǎng)頁地址同時測試啡专,或者將瀏覽器關(guān)閉再重新打開一個新的會話(但這樣的話你就無法關(guān)閉上一次會話創(chuàng)建的用戶)险毁,退出也是只能退出你此次session會話創(chuàng)建的用戶。強制下線功能需要在退出代碼中查找想要退出用戶的sessionID们童,然后將其移除map即可畔况,下面的代碼沒有該功能,可以在此代碼基礎(chǔ)上更改慧库。
代碼:
監(jiān)聽器OnlineLoginUserViewListener.java代碼

package com.qst.chapter02;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;


/**
 * Application Lifecycle Listener implementation class OnlineLoginUserViewListener
 *
 */
@WebListener
public class OnlineLoginUserViewListener implements HttpSessionAttributeListener {

    /**
     * Default constructor. 
     */
    public OnlineLoginUserViewListener() {
        // TODO Auto-generated constructor stub
    }

    /**
     * @see HttpSessionAttributeListener#attributeAdded(HttpSessionBindingEvent)
     */
    @SuppressWarnings("unchecked")
    public void attributeAdded(HttpSessionBindingEvent arg0)  { 
        HttpSession session = arg0.getSession();
        //獲取表示用戶成功登陸后的會話域?qū)傩評sername
        String username = (String) session.getAttribute("username");
        if (username != null) {
            
            //將登陸的用戶信息封裝到j(luò)avabean中
            UserSessionInfo userSessionBean = new UserSessionInfo(username,session.getId(), new Date(session.getCreationTime()));
            
            //map表
            Map<String, UserSessionInfo> onlineRegister = (Map<String, UserSessionInfo>) session.getServletContext().getAttribute("onlineRegister");
            if (onlineRegister == null) {
                
                onlineRegister = new HashMap<String, UserSessionInfo>();
            }
            
            //將登錄信息保存到map中跷跪,key為sessionId
            onlineRegister.put(session.getId(), userSessionBean);
            
            //保存更新后的登陸用戶信息
            session.getServletContext().setAttribute("onlineRegister",onlineRegister);
        }
    }

    /**
     * 刪除session時
     */
    public void attributeRemoved(HttpSessionBindingEvent arg0)  { 
         // TODO Auto-generated method stub
        if ("username".equals(arg0.getName())) {
            HttpSession session = arg0.getSession();
            
            Map<String, UserSessionInfo> onlineRegister = (Map<String, UserSessionInfo>) session
                    .getServletContext().getAttribute("onlineRegister");     
            onlineRegister.remove(session.getId());   
            session.getServletContext().setAttribute("onlineRegister",
                    onlineRegister);
        }
    }

    /**
     * @see HttpSessionAttributeListener#attributeReplaced(HttpSessionBindingEvent)
     */
    public void attributeReplaced(HttpSessionBindingEvent arg0)  { 
         // TODO Auto-generated method stub
    }
    
}

用戶信息javabean,UserSessionInfo.java

package com.qst.chapter02;

import java.io.IOException;
import java.util.Date;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class UserSessionInfo {

    private String username;
    
    private String sessionID;
    
    private Date creationDate;
    
    public UserSessionInfo(){
        
    }

    public UserSessionInfo(String username, String sessionID, Date creationDate) {
        super();
        this.username = username;
        this.sessionID = sessionID;
        this.creationDate = creationDate;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getSessionID() {
        return sessionID;
    }

    public void setSessionID(String sessionID) {
        this.sessionID = sessionID;
    }

    public Date getCreationDate() {
        return creationDate;
    }

    public void setCreationDate(Date creationDate) {
        this.creationDate = creationDate;
    }

}

實時在線用戶顯示頁面onlineLoginUserView.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>view</title>
</head>
<body>
<c:forEach items="${applicationScope.onlineRegister}" var="mapRegister">
        <p>
            用戶名:${mapRegister.value.username},會話創(chuàng)建時間:
            <fmt:formatDate value="${mapRegister.value.creationDate}"
                pattern="yyyy-MM-dd HH:mm:ss" /> 
                <a href="logoutPro.jsp">退出</a>            
        </p>
    </c:forEach>
    <a href="loginPro.jsp">注冊登錄</a>      
</body>
</html>

登陸頁面longinPro.jsp

<%@page import="java.util.Random"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>用戶登錄</title>
</head>
<body>
    <%
    session.setAttribute("username","用戶1"+new Random().nextInt());
    //System.out.print("用戶"+new Random().nextInt());
    response.sendRedirect("onlineLoginUserView.jsp");
    %>
    
</body>
</html>

退出頁面logoutPro.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>用戶退出</title>
</head>
<body>
    <p>已經(jīng)退出本系統(tǒng)齐板!</p> 
    
    <%
    //String username =  request.getParameter("username");
    //System.out.print(username);
    session.removeAttribute("username");
    response.sendRedirect("onlineLoginUserView.jsp");
    %>
    
</body>
</html>

運行效果:
未有用戶注冊時

image.png

有用戶注冊時(需要打開多個瀏覽器測試吵瞻,或者重啟瀏覽器測試)
image.png

退出登陸時(一次會話只能退出當前會話的用戶,所以你只能退出一個用戶)
image.png

總結(jié)

下面是廢話甘磨,可不看橡羞。。济舆。卿泽。
過濾器和監(jiān)聽器是java web中非常重要的兩個功能,可以幫助我們處理很多邏輯上的問題滋觉,通過監(jiān)聽器監(jiān)聽網(wǎng)頁發(fā)出的請求签夭,就可以及時的對請求進行處理齐邦,通過過濾器過濾掉我們不需要的信息,可以大大提高網(wǎng)頁運行的效率第租,也方便程序員對頁面操作進行編程措拇。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市慎宾,隨后出現(xiàn)的幾起案子丐吓,更是在濱河造成了極大的恐慌,老刑警劉巖璧诵,帶你破解...
    沈念sama閱讀 217,084評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件汰蜘,死亡現(xiàn)場離奇詭異,居然都是意外死亡之宿,警方通過查閱死者的電腦和手機族操,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,623評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來比被,“玉大人色难,你說我怎么就攤上這事〉茸海” “怎么了枷莉?”我有些...
    開封第一講書人閱讀 163,450評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長尺迂。 經(jīng)常有香客問我笤妙,道長,這世上最難降的妖魔是什么噪裕? 我笑而不...
    開封第一講書人閱讀 58,322評論 1 293
  • 正文 為了忘掉前任蹲盘,我火速辦了婚禮,結(jié)果婚禮上膳音,老公的妹妹穿的比我還像新娘召衔。我一直安慰自己,他們只是感情好祭陷,可當我...
    茶點故事閱讀 67,370評論 6 390
  • 文/花漫 我一把揭開白布苍凛。 她就那樣靜靜地躺著,像睡著了一般兵志。 火紅的嫁衣襯著肌膚如雪醇蝴。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,274評論 1 300
  • 那天想罕,我揣著相機與錄音哑蔫,去河邊找鬼。 笑死,一個胖子當著我的面吹牛闸迷,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播俘枫,決...
    沈念sama閱讀 40,126評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼腥沽,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了鸠蚪?” 一聲冷哼從身側(cè)響起今阳,我...
    開封第一講書人閱讀 38,980評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎茅信,沒想到半個月后盾舌,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,414評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡蘸鲸,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,599評論 3 334
  • 正文 我和宋清朗相戀三年妖谴,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片酌摇。...
    茶點故事閱讀 39,773評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡膝舅,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出窑多,到底是詐尸還是另有隱情仍稀,我是刑警寧澤,帶...
    沈念sama閱讀 35,470評論 5 344
  • 正文 年R本政府宣布埂息,位于F島的核電站技潘,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏千康。R本人自食惡果不足惜享幽,卻給世界環(huán)境...
    茶點故事閱讀 41,080評論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望吧秕。 院中可真熱鬧琉闪,春花似錦、人聲如沸砸彬。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,713評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽砂碉。三九已至蛀蜜,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間增蹭,已是汗流浹背滴某。 一陣腳步聲響...
    開封第一講書人閱讀 32,852評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人霎奢。 一個月前我還...
    沈念sama閱讀 47,865評論 2 370
  • 正文 我出身青樓户誓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親幕侠。 傳聞我的和親對象是個殘疾皇子帝美,可洞房花燭夜當晚...
    茶點故事閱讀 44,689評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 一、實驗內(nèi)容 1晤硕、Filter的理解和應(yīng)用實現(xiàn)一個禁止緩存的過濾器悼潭。要求和提示:(1)禁止瀏覽器緩存所有動態(tài)頁面;...
    Topus閱讀 2,151評論 4 7
  • Servlet過濾器是 Servlet 程序的一種特殊用法舞箍,主要用來完成一些通用的操作舰褪,如編碼的過濾、判斷用戶的登...
    重山楊閱讀 1,223評論 0 12
  • 經(jīng)典的Java面試題(第二部分)疏橄,這部分主要是與Java Web和Web Service相關(guān)的面試題占拍。 96、闡述...
    nnngu閱讀 692評論 0 8
  • 這部分主要是與Java Web和Web Service相關(guān)的面試題软族。 96刷喜、闡述Servlet和CGI的區(qū)別? 答...
    雜貨鋪老板閱讀 1,404評論 0 10
  • 叮咚!筆試OKA⒃摇R创!面試加油?抛!W巧痢! 就說嘛螺戳,逼自己一下搁宾,沒什么不可以!>笥住盖腿! 加油,鹿小葵K鹜t娓!8嗳肌茂卦! 雖然運氣占百分...
    WDiubiudiu閱讀 283評論 0 1