java學習筆記—使用HttpSession實現QQ的訪問記錄(31)

1. 編寫QQ空間數據類(QQS.java)html

public class QQS {
    private static LinkedHashMap<Integer, String> qqs = 
new LinkedHashMap<Integer, String>();
    static{
        qqs.put(10001, "張三");
        qqs.put(10002, "李四");
        qqs.put(10003, "王五");
        qqs.put(10004, "趙六");
        qqs.put(10005, "田七");
        qqs.put(10006, "焦八");
        qqs.put(10007, "侯九");
        qqs.put(10008, "柳十");
        qqs.put(10009, "小二");
    }
    public static LinkedHashMap<Integer, String> getQqs() {
        return qqs;
    }
}

2. 編寫一個現實QQ數據和瀏覽記錄的頁面(ListServlet.java)java

public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
        // 獲取Session對象
        HttpSession session = request.getSession();
        // 設置中文數據
        response.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");
        // 獲取輸出流
        PrintWriter out = response.getWriter();
        // 獲取QQS數據
        LinkedHashMap<Integer, String> qqs = QQS.getQqs();
        Set<Map.Entry<Integer, String>> set = qqs.entrySet();
        Iterator<Map.Entry<Integer, String>> it = set.iterator();
        // 輸出頁面結構
        out.println("<html><head><title>QQ列表</title><style>a{margin-right:20px;}</style></head><body>");
        out.println("<hr/><br/>");
        out.println("<h3>QQ列表</h3>");
        out.println("<hr/><br/>");
        // 循環輸出QQ空間的超連接
        while(it.hasNext()){
          Map.Entry<Integer, String> entry = it.next();
          Integer num = entry.getKey();
          String name = entry.getValue();
          out.println("<a href=\"/day08/store?num="+num+"\">"+name+"</a>");
        }
        // 輸出瀏覽的記錄信息
        out.println("<hr/><br/>");
        out.println("<h3>QQ瀏覽記錄</h3>");
        out.println("<hr/><br/>");
        // 獲取訪問記錄數據
        String history = (String) session.getAttribute("history");
        if(history == null){
            out.println("<font color=\"red\">對不起,目前沒有訪問記錄...</font>");
        }else{
            // 循環遍歷用戶訪問的記錄數據
            String[] nums = history.split(",");
            for(String num:nums){
                String name = QQS.getQqs().get(Integer.parseInt(num));
                out.println(name+" ,");
            }
        }
        // 關閉頁面結構
        out.println("</body></html>");
    }

3. 編寫一個存儲瀏覽QQ空間的頁面(StoreQQServlet.java)web

public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
        // 獲取Session對象
        HttpSession session = request.getSession(false);
        // 獲取請求參數
        String num = request.getParameter("num");
        // 獲取Session中的數據
        String history = (String) session.getAttribute("history");
        // 判斷數據
        if(history == null){
            // 第一次訪問
            session.setAttribute("history", num);    // history=10001
        }else{
            // 訪問屢次
            session.setAttribute("history", history+","+num);
            // 設置num的數量和顯示的順序
            String[] qqs = history.split(",");
            // 將數組轉換爲方便操做的集合
            List<String> list = Arrays.asList(qqs);
            // 將List轉換爲LinkedList便於操做數據
            LinkedList<String> linked_list = new LinkedList<String>();
            linked_list.addAll(list);
            // 判斷出現的QQ次數
            if(qqs.length < 3 ){
                if(linked_list.contains(num)){  // history=10002,1003   
                    // 若是包含
                    linked_list.remove(num);
                    linked_list.addFirst(num);
                }else{                         // history=1004,10002,1003    
                    // 不包含 
                    linked_list.addFirst(num);
                }
            }else{   // >= 3
                if(linked_list.contains(num)){  
// history=10002,10003,10004   10004 
                    // 若是包含
                    linked_list.remove(num);
                    linked_list.addFirst(num);
                }else{                         // history= 10005 ,10002,10003      
                    // 不包含 
                    linked_list.removeLast();
                    linked_list.addFirst(num);
                }
            }
            // 次數好了,順序好了的訪問記錄linked_list
            StringBuffer sb = new StringBuffer();
            for(String new_num:linked_list){
                sb.append(new_num+",");
            }
            String new_history = sb.toString();
            session.setAttribute("history", new_history);
        }
        // 重定向到QQ列表頁面
        response.sendRedirect("/day08/list");
    }

以上的代碼將用戶的瀏覽記錄存儲在了session對象中,可是該對象是在服務器內存中的,且有有效的時間限制,若是時間到了,那麼session就會被銷燬。數組

默認的時間爲半個小時(30分鐘)。瀏覽器

4  配置Session的有效時間服務器

在每個網站的web.xml中能夠配置該網站建立的session對象的有效時間。注意的是配置時單位是分鐘。session

Thread.slessp(毫秒單位)、Cookie.setMaxAge(秒單位)、session(分鐘單位)app

  <session-config>
    <session-timeout>2</session-timeout>         單位是分鐘
  </session-config>

5  Cookie的禁用less

Cookie能夠利用客戶端存儲會話數據。網站

HttpSession能夠利用Cookie存儲SessionID信息。

其實在瀏覽器的設置中能夠拒絕網站發送回來的Cookie信息。

 

此時再訪問以上的案例就會致使空指針異常出現。若是須要將網站修復,那麼必須使用URLRewriting技術。

URLRewritting

分析以上問題的緣由:

服務器建立好了Session對象,可是因爲瀏覽器禁止了Cookie的接收,那麼服務器沒法將建立好的Session的ID值以Set-Cookie的響應頭方式發送給瀏覽器進行存儲,那麼在第二訪問的時候也就不會懈怠SessionID,所以沒法找到Session。

經常使用的方法

String encodeRedirectURL(String url)      給指定的重定向路徑後添加Sessionid信息
String encodeURL(String url)             給普通的URL地址添加Sessionid信息

實施的原則:

「將頁面中的全部的URL地址所有使用以上方法進行從新編碼」

1 修改以上程序

1 ListServlet.java

String path = "/day08/store?num="+num;
  path = response.encodeURL(path);
  out.println("<a href='"+path+"'>"+name+"</a>");

2. StoreQQServlet.java

String path = "/day08/list";
path = response.encodeRedirectURL(path);
response.sendRedirect(path);
相關文章
相關標籤/搜索