java攻城師之路--復習java web之Cookie_Session


Servlet技術 用來動態生成 網頁數據資源
Servlet生成HTML 頁面數據時,所有內容都是通過 response.getWriter response.getOutputStream 向瀏覽器輸出的

1 <html>
2 <head>
3 </head>
4 <body>
5      Hello
6 </body>
7 </html>

用Servlet 輸出流打印網頁信息
response.getWriter().print("<html>");

Servlet生成網頁缺點
1、通過print輸出網頁 開發很不方便
2、美工人員經常對頁面進行CSS修飾,美工人員在java代碼中調試CSS
3、無法使用開發工具對頁面代碼進行調試 JS CSS

98前后 主流網頁設計技術 ASP PHP , sun推出Servlet,sun參考ASP語法推出JSP
* 什么是 JSP ? JSP 和Servlet技術一樣,都是動態網頁開發技術
* JSP 和 Servlet 關系? JSP在運行時,需要先翻譯為Servlet才能運行 ------ JSP 就是 Servlet
Servlet2.5 版本 ---- JavaEE 5.0 ---- JSP 版本2.1

編寫第一個JSP程序
1、JSP位於WebRoot下 --- 不能放入WEB-INF(不能訪問)
2、修改JSP默認編碼 window --- preferences --- JSP 修改編碼 utf-8
3、修改JSP 默認編輯器 window --- preferences --- general ---- editor ---- File Associations 將 JSP編輯器改為 JSP Editor
4、在WebRoot下 新建 JSP ---- hello.jsp
5、寫JSP過程和編寫HTML一樣,可以通過<%%> 嵌入java代碼

* 有人比喻 Servlet:嵌入HTML的java文件 ; JSP :嵌入Java的HTML文件

JSP運行原理:
1、客戶端訪問hello.jsp
2、服務器讀取hello.jsp內容到內存
3、服務器根據hello.jsp內容生成Servlet程序 ----保存在哪? tomcat/work
4、Servlet編譯運行

JSP翻譯Servlet 固定包名 :org.apache.jsp
hello.jsp ---- hello_jsp.java

JSP中 HTML代碼 <%%> 代碼都會被翻譯Servlet 中 _jspService
翻譯規則:
1、JSP 中 HTML 翻譯 out.write
2. JSP中java代碼 不會翻譯

JSP中腳本元素
1、聲明 <%! %> --- 定義內容將會被翻譯Servlet類 成員變量和方法
2、表達式 <%= %> ---- 用於向頁面輸出內容 等價於 out.print()
3、代碼塊<% %> --- 在<%%> 之間編寫任何java代碼
* 代碼塊可以和html嵌套使用

<%@ 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>
<%! int a= 5; %> 
<%=a %><br/>
<% 
    for(int i=0;i<=10;i++){
    out.print(a); 
%>
    <br/>
<% 
    }
%>
</body>
</html>
myfirst.jsp

開發網頁程序,使用Servlet? 使用JSP呢?
Java代碼多 --- Servlet
HTML代碼多 ---- JSP

JSP運行時 總要翻譯Servlet ,效率很低 ?
* 只有第一次訪問JSP 進行翻譯 ,以后訪問,如果沒有修改 JSP 不會重新翻譯

EL 全名為Expression Language ---- 表達式語言
語法:${標識符}
${applicationScope.name } 等價於 <%=getServletContext().getAttribute("name") %>
${requestScope.address } 等價於 <%=request.getAttribute("address") %>

<%@ 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>
<%
     getServletContext().setAttribute("name", "shellway");
     request.setAttribute("name", "天用");
%>
   <h1>通過JSP獲取</h1>
<%=getServletContext().getAttribute("name") %>
<%=request.getAttribute("name") %>
   <h1>通過EL獲取</h1>
  ${applicationScope.name }
  ${requestScope.name }
</body>
</html>
el.jsp

JSTL (JSP Standard Taglib Liberary) --- JSP 標准標簽庫
JSTL干嘛用的? 簡化頁面<%%> 與 HTML嵌套寫法 ----- 簡化JSP開發

今天學習目標: <c:forEach> <c:if> ----- 用來替換頁面中for循環 和 if條件判斷

在頁面內使用JSTL 簡化 if 和 for
1、導入jstl的jar包 --- MyEclipse中存在 javaee5 類庫 ---存在 jstl1.2.jar
2、在頁面最上方 <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
* 定義了很多標簽,為標簽指定名稱空間 uri ,在使用標簽前 引用名稱空間
JSTL+EL 簡化 <%%> 腳本代碼

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core"  prefix="c"%> 
<!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>頁面內編寫if條件</h1>
<% 
     int i =10 ;
     if(i>8){
%>
  i的值大於8
<% 
     }   
%>
<h1>頁面內用jstl編寫if條件</h1>
<%
  request.setAttribute("i", 10);
%>
<c:if test="${requestScope.i>8}">
     i的值大於8
</c:if>

</body>
</html>
jstl_if.jsp
<%@page import="org.apache.taglibs.standard.tag.common.core.ForEachSupport"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core"  prefix="c"%> 
<!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>通過%寫for循環</h1>
<%
    int[] arr = {1,2,3,4,5};
    for(int i:arr){
%>
     i的值是:<%=i %> <br/>
<% 
    }
%>
<h1>通過jstl寫for循環</h1>
<%  
   request.setAttribute("arr", new int[]{6,7,8,9,10});
%>
<c:forEach items="${requestScope.arr}" var="i">
  i的值是:${i } <br/>
</c:forEach>
</body>
</html>
jstl_foreach.jsp

------------------------------------------------------------------------------------------------------
什么是會話? 用戶打開瀏覽器,訪問站點,連續進行多次操作,關閉瀏覽器 ,整個過程稱為會話 。

管理HTTP協議會話狀態 :Cookie 和Session
Cookie:將用戶相關數據,保存客戶端 , 用戶每次訪問服務器自動攜帶cookie數據 。
Session : 將用戶相關數據 保存服務器端,為每個客戶端生成一個獨立Session數據對象,通過對象唯一編號,區分哪個瀏覽器對應 哪個Session

Cookie快速入門 案例:上次訪問時間
1、通過服務器向客戶端寫cookie
Cookie cookie = new Cookie(name,value);
response.addCookie(cookie);
* 在HTTP協議響應頭信息中 Set-Cookie: last=1339556457609

2、當客戶端存在cookie之后,以后每次請求自動攜帶 HTTP協議請求頭信息 Cookie: last=1339556456859
服務器端獲得需要cookie數據
Cookie[] cookies = request.getCookies(); ---- 獲得客戶端所有cookie
if(cookies==null){} 判斷cookie是否存在

遍歷cookie獲得需要信息
for (Cookie cookie : cookies) {
// 獲得每個cookie
if (cookie.getName().equals("last")) {
// 找到了需要cookie
}
}

CookieAPI 詳解
1、將cookie寫回客戶端 response.addCookie(cookie);
2、讀取請求中 cookie信息 request.getCookies
3、Cookie對象創建 new Cookie(name,value )
* cookie的name 不允許改變 ----- getName 、getValue 、setValue

4、什么是會話cookie ,什么是持久cookie ?
cookie信息默認情況 保存在瀏覽器內存中 ------ 會話cookie
會話cookie 會在關閉瀏覽器時 清除

持久Cookie,cookie數據保存客戶端硬盤上
通過setMaxAge 設置Cookie為持久Cookie
* 在JavaAPI 中所有與時間相關參數,int 類型 單位秒, long類型 單位毫秒

5、訪問cookie有效路徑path
默認情況下,生成cookie時,產生默認有效訪問路徑 (默認生成cookie程序路徑)
http://localhost/day07/lastvisit --- 生成cookie --- path 默認值: /day07
http://localhost/day07/servlet/path ---- 生成cookie ---- path 默認值:/day07/servlet

第二次訪問程序攜帶cookie信息,如果訪問路徑與path不一致,不會攜帶cookie 信息
company cookie : path --- /day07/serlvet
last cookie : path --- /day07

訪問 :http://localhost/day07/servlet/path ---- 同時滿足/day07/serlvet、/day07 攜帶 company 和 last兩個cookie信息
訪問 :http://localhost/day07/lastvisit ---- 滿足 /day07 不滿足/day07/serlvet 攜帶 last 一個cookie 信息
* 以后程序開發,盡量設置path ---- setPath方法

6、第一方cookie 和 第三方cookie
通過setDomain 設置cookie 有效域名
訪問google時,生成cookie過程中 cookie.setDomain(".baidu.com") ---- 生成百度cookie ------ 第三方cookie
* 第三方cookie 屬於不安全 ----- 一般瀏覽器不接受第三方cookie

訪問google時,生成cookie,cookie.setDomain(.google.con) ---- 生成google的cookie ------ 第一方cookie

案例:刪除上次訪問時間
原理:設置cookie MaxAge為 0
* 刪除cookie時 必須設置path 與cookie的 path一致


案例:商品瀏覽記錄 ---- 可以通過Cookie實現

<%@page import="com.shellway.servlet.cookie.CookieUtils"%>
<%@ 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>
 <h3>商品購買</h3>
      <a href="/day05/cookie3?shoppinginfo=1">筆記本</a><br/>
      <a href="/day05/cookie3?shoppinginfo=2">冰箱</a><br/>
      <a href="/day05/cookie3?shoppinginfo=3">空調</a><br/>
      <a href="/day05/cookie3?shoppinginfo=4">熱水器</a><br/>
      <a href="/day05/cookie3?shoppinginfo=5">微波爐</a><br/>
      <a href="/day05/cookie3?shoppinginfo=6">電磁爐</a><br/>
      <a href="/day05/cookie3?shoppinginfo=7">電飯鍋</a><br/>
 <h3>您剛瀏覽過的商品</h3> <a href="/day05/cleanhistory">清空瀏覽記錄</a><br/><br/><br/>
 <%
 /*        Cookie[] cookies = request.getCookies();
       String[] arr = {"筆記本","冰箱","空調","熱水器","微波爐","電磁爐","電飯鍋"};
       if(cookies==null){
       out.print("無商品瀏覽記錄");
       }else{
             for(Cookie c : cookies){
               if( c.getName().equals("history")){
                 String id =  c.getValue();
                 out.println(arr[Integer.parseInt(id)-1]);
               }
             }
       } 
 */       
       String[] arr = {"筆記本","冰箱","空調","熱水器","微波爐","電磁爐","電飯鍋"};
       Cookie cookie = CookieUtils.findCookie(request.getCookies(), "history");
       if(cookie==null){
         out.println("無商品瀏覽記錄");
       }else{
          String ids = cookie.getValue();
          String[] idArr = ids.split(",");
          for(String id : idArr){
             out.println(arr[Integer.parseInt(id)-1]+"<br/>");
          }
       }
 %>
</body>
</html>
頁面:history.jsp
package com.shellway.servlet.cookie;

import javax.servlet.http.Cookie;

public class CookieUtils {
   public static Cookie findCookie(Cookie[] cookies,String name){
       if (cookies==null) {
           //無cookie信息
           return null;
    }else{
        for (Cookie cookie : cookies) {
            if (cookie.getName().endsWith(name)) {
                return cookie;
            }
        }
    }
       return null;
   }
}
工具類:CookieUtils.java
package com.shellway.servlet.cookie;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ServletCookie3 extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //從客戶端獲得商品ID
        String id = request.getParameter("shoppinginfo");
        String[] arr = {"筆記本","冰箱","空調","熱水器","微波爐","電磁爐","電飯鍋"};
        
        //向客戶端添加Cookie
/*        Cookie cookie = new Cookie("history", id);
        cookie.setMaxAge(60*60);
        cookie.setPath("/day05");
        response.addCookie(cookie);*/
        
        response.setContentType("text/html;charset=utf-8");
        response.getWriter().println("您正在瀏覽商品:"+arr[Integer.parseInt(id)-1]+
             "&nbsp&nbsp&nbsp&nbsp"+"<a href='/day05/cookie/history.jsp'>返回<a/>");
        Cookie cookie = CookieUtils.findCookie(request.getCookies(), "history");
        if (cookie == null) {
            cookie = new Cookie("history", id);
            cookie.setMaxAge(60*60);
            cookie.setPath("/day05");
            response.addCookie(cookie);
        }else{
            //判斷當前商品是否已經在瀏覽記錄中
            String ids = cookie.getValue();
            //用逗號分割開判斷當前的商品編號與歷史瀏覽記錄中的編號是否一致
            String[] idArr = ids.split(",");
            for (String s : idArr) {
                if (s.equals(id)) {
                    //如果存在就返回,不執行后面的代碼
                    return;
                }
            }
            //如果不存在就給Cookie的值拼接上當前商品的編號
            cookie.setValue(ids+","+id);
            cookie.setMaxAge(60*60);
            cookie.setPath("/day05");
            response.addCookie(cookie);
        }
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        doGet(request, response);

    }
}
主程序:ServletCookie3
package com.shellway.servlet.cookie;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class CleanHistoryServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        Cookie cookie = new Cookie("history","");
        cookie.setMaxAge(0);
        cookie.setPath("/day05");
        response.addCookie(cookie);
        response.sendRedirect("/day05/cookie/history.jsp");
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        doGet(request, response);

    }
}
刪除歷史瀏覽記錄: CleanHistoryServlet.java

----------------------------------------------------------------------------------------------------------

Session 是服務器端會話管理技術,服務器會為每個瀏覽器創建一個單獨Session對象,保存該瀏覽器(會話)操作相關信息。
與Cookie區別:cookie是保存在客戶端,Session保存在服務器端

為什么有Cookie技術?還需要Session ?
Cookie 存在客戶端 ----存在安全問題
Session將數據存在服務器,數據更加安全
* Session將數據保存在服務器端,占用服務器內存資源 ,Cookie不會占用服務器資源
例如:京東購物車信息 保存Cookie 、淘寶購物車信息保存Session

Session共享
實驗:用IE6 向Session保存一個數據,用另一個IE6讀取數據?
用第一個IE6保存session數據,當前瀏覽器可以獲得,但是第二個IE6 無法獲得第一個瀏覽器保存Session 數據

IE8以上 或 火狐瀏覽器:當打開多個瀏覽器窗口,之間Session共享

原因:IE6 cookie 中保存jsessionId 默認會話級別 ;IE8或者火狐 保存cookie中 jsessionId 默認持久cookie

問題:如何讓多個IE6 共享同一個Session ---- 將session id 持久化

問題:如果客戶端關閉瀏覽器,是否就刪除了Session ?
沒有,Session保存在服務器端

問題:IE6 保存Session,關閉瀏覽器,再次打開,數據丟失了?
IE6默認jsessionId保存會話Cookie中,關閉瀏覽器,會話cookie就會被刪除,客戶端丟失jsessionid 無法找到服務器對應Session對象
* 服務器Session對象還存在

Session購物車案例
1、商品列表,用戶點擊列表中商品,將商品添加購物車
2、查看購物車中商品,以及商品購買件數

禁用Cookie后,Session還能否使用?
可以,可以對url進行重寫,原理在url;jsessionid=xxx ---- 在程序中可以調用response.encodeURL進行URL重寫
* 如果服務器進行URL重寫,所有路徑都必須重寫
* 不要讓用戶禁用cookie

Cookie生命周期
Cookie 對象何時創建,何時銷毀
創建 : Cookie cookie = new Cookie(name,value) ; response.addCookie(cookie);
銷毀 : 會話cookie會在瀏覽器關閉時銷毀,持久cookie會在cookie過期(MaxAge)后銷毀

Session生命周期
創建:request.getSession() 創建Session
銷毀:三種 1、服務器關閉時銷毀 2、session過期時銷毀 3、手動調用session.invalidate

設置session過期時間
1、配置web.xml
<session-config>
<session-timeout>30</session-timeout>
</session-config>
2、調用session對象 setMaxInactiveInterval(int interval) 單位是秒
HttpSession session = request.getSession();
session.setMaxInactiveInterval(60*60); 設置session過期時間1小時

案例:Session經常用來完成系統權限和認證功能
權限:在用戶身份認證后,根據權限知道 --- 你能做什么
認證:用戶登陸 --- 你是誰

將登陸用戶信息保存到Session 有什么作用 ? ---- 如果session中沒有用戶信息 未登陸


案例:通過session實現一次性驗證碼
* 驗證碼從session獲取后,馬上刪除 ---- 驗證碼只能使用一次

---------------------------------------------------------------------------------------
Servlet 三種數據范圍
ServletContext
HttpServletRequest
HttpSession

三種數據范圍,每個對象各自維護類似map集合結構,具備相同幾個方法
setAttribute 存入一個屬性
getAttribute 取出一個屬性
removeAttribute 移除一個屬性

三種數據范圍對象 在哪些情況使用?
ServletContext 服務器啟動時創建,服務器關閉銷毀 所有Servlet共享 ---- 保存一些全局數據
例如:數據庫連接池、工程配置屬性、配置文件內容 ----- 一般不建議使用

HttpSession 在request.getSession時創建,在三種情況下銷毀 ----- 保存與用戶相關數據
例如:系統登陸信息、購物車數據

HttpServletRequest 在客戶端發起請求時,服務器創建對象,在響應結束時 對象銷毀 ----- 保存Servlet向JSP傳輸數據信息
例如:執行某個操作,Servlet將操作結果傳遞JSP (Servlet將登陸錯誤信息傳遞JSP )、Servlet將數據庫查詢結果傳遞JSP

以上三種數據范圍 ServletContext > HttpSession > HttpServletRequest
* 宗旨 優先使用生命周期短的


總結 :
day5
1、編寫一個Servlet --- HelloWorld response.getWriter().print()
2、設置response編碼集,向瀏覽器輸入中文信息 response.setContentType("text/html;charset=utf-8");
3、將九九乘法表打印瀏覽器頁面 ----- 添加for循環
4、編寫頁面讓用戶輸入一個數字,在Servlet根據用戶輸入數字 打印乘法表
5、用戶輸入一段字母內容,在瀏覽器上輸入 每個字符出現幾次
6、網站訪問次數 (選做)
7、讀取web工程中一個文件 (getServletContext().getRealPath())


理論:
1、Servlet生命周期
2、ServletConfig和ServletContext
3、url-pattern 三種寫法

day6
1、重定向 ---- response.setStatus response.setHeader
2、自動跳轉 ---- refresh
3、禁用緩存 ---- 三個頭信息
4、文件下載 (復雜值得做)
5、驗證碼程序 整理一下 (不用重寫)
6、獲得當前訪問資源路徑 request.getRequestURI().substring(request.getContextPath().length());
7、獲得客戶端 IP request.getRemoteAddr()
8、防盜鏈 request.getHeader(referer)
9、獲得請求參數 亂碼問題 post get 亂碼解決 (昨天重點**** )

理論:
1、200、302 、304 、404 、500 意思
2、refrer refresh Content-Type Content-Disposition 禁止緩存三個頭 ----- 含義
3、get和post請求方式區別
4、亂碼發生原因 (掌握)

day7
1、記錄上次訪問時間 cookie
2、商品瀏覽記錄 cookie
3、商品購物車 session
4、登陸一次性驗證碼 session

理論:
1、cookie和session區別
2、會話cookie 和持久cookie
3、第一方cookie和第三方cookie
4、關閉瀏覽器是否清除cookie ?
5、持久cookie刪除
6、關閉瀏覽器,重新打開瀏覽器session還能繼續使用 ?原理 ?
7、瀏覽器禁用cookie,session還能否使用
8、session銷毀三種情況
9、一次性驗證碼原理
10、Servlet三種數據范圍區別

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM