11 - JSP/cookie/HttpSession

本文目錄:

  1. JSP基礎(chǔ)
  2. Cookie
  3. HttpSession

JSP基礎(chǔ)

JSP(Java Server Pages)是JavaWeb服務(wù)器端的動態(tài)資源。它與html頁面的作用是相同的,顯示數(shù)據(jù)和獲取數(shù)據(jù)。

jsp和Servlet的常見分工

(jsp) request -- servlet -- (jsp) response

  • JSP
    • 作為請求發(fā)起頁面,把來自用戶的post/get等請求發(fā)送給servlet:例如頁面內(nèi)含有表單、超鏈接
    • 作為請求結(jié)束頁面,接受servlet的數(shù)據(jù),顯示給用戶。
  • Servlet
    • 獲取jsp發(fā)送來的請求參數(shù)
    • 處理請求,得到處理后的數(shù)據(jù)
    • 把結(jié)果保存到request中
    • 轉(zhuǎn)發(fā)到顯示結(jié)果的JSP

jsp的作用

  • Servlet
    • 優(yōu)點:動態(tài)資源(html靜態(tài)頁面不能包含動態(tài)信息)
    • 缺點:不適合設(shè)置html代碼,需要大量的response.getWriter().print("<html>")
  • jsp(java server pages)
    • jsp文件內(nèi)容:直接在原有html代碼的基礎(chǔ)上,添加java腳本。很方便。

jsp的組成 jsp = html + java腳本 + jsp標(biāo)簽(指令)

  • JSP標(biāo)簽 有2種:

  • JSP指令元素<%@ %>

  • JSP動作元素<jsp: />

  • jsp的9大內(nèi)置對象(無需創(chuàng)建即可使用的對象):

    • request
    • response
    • out
    • session
    • application 和tomcat進程“共生死”
    • pageContext
    • config
    • page
    • exception

3種java腳本

<% java代碼片段 %>
<!--,常用
可寫0到n條Java語句
方法內(nèi)能寫什么,它就可以寫什么
-->


<%=表達(dá)式 %>

<!--java表達(dá)式,用于輸出一條表達(dá)式(或變量)的結(jié)果。-->
response.getWriter().print( ... );
<!--這里能放什么,它就可以放什么!
比如某個具有返回值的函數(shù) func1()
-->



<%!聲明 成員變量等 %> 
<!--聲明,用來創(chuàng)建類的成員變量和成員方法(基本不用,但容易被考到)
類體中可以放什么,它就可以放什么!

Class man{
成員變量
成員方法
構(gòu)造器
構(gòu)造代碼塊
靜態(tài)塊
內(nèi)部類
}

-->

out.print()和out.write() 幾乎沒有區(qū)別:

String s = null;
out.print(s); // outputs the text "null"  處理空指針異常,輸出字符串“null”。
out.write(s); // NullPointerException  不處理該異常。

jsp注釋

<%-- 當(dāng)服務(wù)器把jsp編譯成java文件前就沒有這些注釋了! --%> 
<!--  html注釋會發(fā)到客戶端瀏覽器。 -->

案例:演示jsp中java腳本的使用!
案例:演示jsp與servlet分工!

jsp原理(理解)

  • 當(dāng)jsp頁面第一次被訪問時:
    • 1.服務(wù)器會把jsp編譯成java文件(這個java其實是一個servlet類)
    • 2.再把java編譯成.class
    • 3.創(chuàng)建該類對象
    • 4.最后調(diào)用它的service()方法
  • 第二次請求某jsp時,直接調(diào)用service()方法。
jsp實質(zhì)是一種特殊的Servlet

tomcat/work/Catalina目錄下可以找到 jsp 對應(yīng)的 .java 源代碼,和生成的.class文件。

  • 查看jsp對應(yīng)java文件:
  • .java語句,方法體的最上面,聲明了9大內(nèi)置對象,賦值。
  • 原封不動的把程序員寫的代碼放到方法體下面。
  • html語句,全是這樣輸出的:out.wirte("字符串");

Cookie

Http協(xié)議與Cookie
  • Cookie是HTTP協(xié)議制定的!
    服務(wù)器保存Cookie到瀏覽器,再下次瀏覽器請求服務(wù)器時,會帶上Cookie
  • 由服務(wù)器創(chuàng)建保存到客戶端瀏覽器的一個鍵值對!”key=value“

服務(wù)器保存Cookie的響應(yīng)頭
Set-Cookie: aaa=AAA Set-Cookie: bbb=BBB

response.addHeader("Set-Cookie", "aaa=AAA");
response.addHeader("Set-Cookie", "bbb=BBB");
  • 當(dāng)客戶端瀏覽器發(fā)送request給服務(wù)器時,會帶上Cookie:
Cookie: aaa=AAA; bbb=BBB
  • Http協(xié)議規(guī)定(很多瀏覽器都會在一定范圍內(nèi)違反HTTP規(guī)定)
    • 1個Cookie最大4KB
    • 1個服務(wù)器最多向1個瀏覽器保存20個Cookie
    • 1個瀏覽器最多可以保存300個Cookie
Cookie的用途

注意Cookie不跨瀏覽器!

  • 跟蹤客戶端狀態(tài)
  • 保存購物車信息
  • 只保存上次的登錄名,方便登錄。
JavaWeb中使用Cookie
  • 原始方式(了解)
  • 使用response發(fā)送Set-Cookie響應(yīng)頭
  • 使用request獲取Cookie請求頭
  • 便捷方式(重要?。?/li>
repsonse.addCookie()//讓瀏覽器端保存Cookie

request.getCookies()//獲取瀏覽器端帶來的Cookie
//如果HTTP請求沒有帶來cookie則返回null

服務(wù)器端發(fā)送response給客戶端瀏覽器,http響應(yīng)包頭中有Set-Cookie頭,格式如下:

Set-Cookie: key1=value2
Set-Cookie: key1=value2
Set-Cookie: key1=value2

客戶端發(fā)送request給服務(wù)器時,http請求包頭里面有Cookie頭,格式如下:

Cookie: key1=value1; key2=value2; key3=value3
Cookie詳解
  • Cookie不只有name和value兩個屬性
  • Cookie的maxAge
    • maxAge>0:Cookie的最大生命。瀏覽器會把Cookie保存到客戶機硬盤上,有效時長為maxAge的值,以秒為單位。cookie.setMaxAge(60)
    • maxAge<0:Cookie只在瀏覽器內(nèi)存中存在(瀏覽器進程結(jié)束,Cookie消失)
    • maxAge=0:立即刪除同名cookie
  • Cookie的path
    • Cookie的path決定:當(dāng)瀏覽器訪問服務(wù)器某個路徑時,帶上哪些Cookie
    • Cookie的path不可能是設(shè)置這個Cookie在客戶端的保存路徑!
    • Cookie的path由響應(yīng)包response創(chuàng)建Cookie時設(shè)置
    • 瀏覽器訪問服務(wù)器的路徑,如果包含某個Cookie的路徑,那么就會帶上這個Cookie。

例如:服務(wù)器端設(shè)置

aCookie.path=/day11_1/; 
bCookie.path=/day11_1/aaa/; 
cCookie.path=/day11_1/aaa/bbb/;

客戶端瀏覽器
訪問:域名/day11_1/anyname.jsp 時帶上aCookie
訪問:域名/day11_1/aaa/anyname.jsp 時帶上aCookie、bCookie
訪問:域名/day11_1/aaa/bbb/anyname.jsp 時帶上aCookie、bCookie、cCookie

  • Cookie的path默認(rèn)值:當(dāng)前訪問路徑的父路徑。
    如訪問/day11_1/jsps/a.jsp時響應(yīng)包設(shè)置了cookie,該cookie的默認(rèn)path為/day11_1/jsps/
cookie.setDomain(".baidu.com");//設(shè)置domain  直接省略掉二級域名的不同之處
cookie.setPath("/");//設(shè)置path
  • 自己測試,步驟:
  1. 修改本機hosts文件
    127.0.0.1 111.x.com
    123.0.0.1 222.x.com

  2. 在${CATALINA_HOME}/conf/server.xml中添加配置
    <Host name="news.qdmmy6.com" appBase="news"
    unpackWARs="true" autoDeploy="true">
    </Host>
    <Host name="tieba.qdmmy6.com" appBase="tieba"
    unpackWARs="true" autoDeploy="true">
    </Host>

  3. 把tieba和news兩個目錄copy到${CATALINA_HOME}下

  4. 訪問http://news.qdmmy6.com/SaveServlet

  5. 訪問http://tieba.qdmmy6.com/GetServlet

Cookie保存中文

Cookie的name和value都是不能直接保存中文的,但可以把中文轉(zhuǎn)換成URL編碼后保存到Cookie(name和value中)

  String name = "姓名";
  String value = "張三";
  name = URLEncoder.encode(name, "utf-8");
  value = URLEncoder.encode(value, "utf-8");

  Cookie c = new Cookie(name, value);
  response.addCookie(c);

  //獲取Cookie:使用URL解碼即可。
  Cookie[] cs = request.getCookies();
  if(cs != null) {
    for(Cookie c : cs) {
      String name = URLDecoder.decode(c.getName(), "utf-8");
      String value = URLDecoder.decode(c.getValue(), "utf-8");
      System.out.println(name + "=" + value);
    }
  }

HttpSession(重點)

HttpSession概述
  • HttpSession是由JavaWeb提供的,用來會話跟蹤的類。session是服務(wù)器端對象,保存在服務(wù)器端?。?!

  • HttpSession底層依賴CookieURL重寫

  • HttpSession是Servlet三大域?qū)ο笾?/p>

  • 三大域?qū)ο?/p>

  • request

    • 每一次請求都會創(chuàng)建一個request
    • 請求鏈共享數(shù)據(jù) 可把request發(fā)給多個Servlet
  • session

    • 會話是同一個用戶在瀏覽器打開后關(guān)閉前對服務(wù)器的多次請求。
  • application(ServletContext)

    • 程序存在,保存在這里的內(nèi)容就一直存在

三大域?qū)ο蠖加蟹椒ǎ?/p>

void setAttribute(String name, Object value);
Object getAttribute(String name);
void removeAttribute(String name);

session是域?qū)ο?,所以有setAttribute()和getAttribute()等方法
服務(wù)器會為每個會話創(chuàng)建一個session對象,所以session中的數(shù)據(jù)可供當(dāng)前會話中所有servlet共享。

會話 會話追蹤
  • 會話:同一個用戶在瀏覽器打開后關(guān)閉前對服務(wù)器的多次請求。
  • 會話范圍:某個用戶從首次訪問服務(wù)器開始,到該用戶關(guān)閉瀏覽器結(jié)束!
  • 會話方便了服務(wù)器端共享數(shù)據(jù)!對客戶端瀏覽器只在Cookie里只有一個session的ID,服務(wù)器端在這個session中設(shè)置的一些值對用戶均不可見。
  • 會話跟蹤技術(shù):在一次會話中共享數(shù)據(jù)。
    HTTP是無狀態(tài)協(xié)議,每個請求之間無法共享數(shù)據(jù)。這就無法知道會話什么時候開始,什么時候結(jié)束,也無法確定發(fā)出請求的用戶身份。這說明需要使用額外的手段來跟蹤會話!
  • session緩存:服務(wù)器會為每個客戶端創(chuàng)建一個session對象,session就好比客戶在服務(wù)器端的賬戶,它們被服務(wù)器保存到一個Map中,這個Map被稱之為session緩存!
  • Servlet中得到session對象HttpSession session = request.getSession();

  • Jsp中得到session對象
    session是jsp內(nèi)置對象,不用創(chuàng)建,直接使用!如
    <%session.setAttribute("aa","bb")%>

案例1:session 多次請求中共享數(shù)據(jù)
  • AServlet:向session域中保存數(shù)據(jù)
  • BServlet:從session域中獲取數(shù)據(jù)
  • 演示:

    第一個請求:訪問AServlet
    第二個請求:訪問BServlet

案例2:session 保存用戶登錄信息(精通)
  • 案例相關(guān)頁面和Servlet:

    • login.jsp:登錄頁面
    • succ1.jsp:只有登錄成功才能訪問的頁面
    • succ2.jsp:只有登錄成功才能訪問的頁面
    • LoginServlet:校驗用戶是否登錄成功!
  • 各頁面和Servlet內(nèi)容:

    • login.jsp:提供登錄表單,提交表單請求LoginServlet
    • LoginServlet:獲取請求參數(shù),校驗用戶是否登錄成功
      • 失?。罕4驽e誤信息到request域,轉(zhuǎn)發(fā)到login.jsp(login.jsp顯示request域中的錯誤信息)
      • 成功:保存用戶信息到session域中,重定向到succ1.jsp頁面,顯示session域中的用戶信息
    • succ1.jsp:從session域獲取用戶信息,如果不存在,顯示“您還沒有登錄”。存在則顯示用戶信息
    • succ2.jsp:從session域獲取用戶信息,如果不存在,顯示“您還沒有登錄”。存在則顯示用戶信息

    只要用戶沒有關(guān)閉瀏覽器,session就一直存在,那么保存在session中的用戶信息也就一起存在!那么用戶訪問succ1和succ2就會通過!

HttpSession原理(理解)

  • request.getSession()方法

    • 獲取Cookie中的JSESSIONID(唯一標(biāo)識)
    • 如果Cookie中沒有sessionId,從url參數(shù)中獲取 格式為;JsessionID=也沒有時,服務(wù)器創(chuàng)建一個session并保存,把新創(chuàng)建的sessionId設(shè)置到瀏覽器Cookie中,這個Cookie的生命為-1,即只在瀏覽器內(nèi)存中存在!
    • 關(guān)閉瀏覽器前,再次請求,服務(wù)器端執(zhí)行request.getSession()方法,通過客戶端帶Cookie的請求,得到Cookie中的sessionId,服務(wù)器的session對象與上一次請求使用的是同一session對象。
    • 如果sessionId存在,但通過sessionId沒有找到session對象(可能超時被服務(wù)器刪除了),創(chuàng)建session保存到服務(wù)器,把新創(chuàng)建的sessionId保存到客戶端瀏覽器的Cookie中
    • 如果sessionId存在,通過sessionId查找到了session對象(不會再創(chuàng)建新session對象)
  • 服務(wù)器不會馬上給用戶創(chuàng)建session,在第一次獲取session時才會創(chuàng)建該用戶的session!

session對象是保存在服務(wù)器端的,而sessionId是通過Cookie保存在客戶端的。
因為Cookie不能在多個瀏覽器中共享,所以session也不能在多個瀏覽器中共享。

//以下都是Servlet的代碼:
//所有Servlet如果不寫這一行,都不會自動創(chuàng)建session(不會給客戶端Set-Cookie)
request.getSession();//如果是服務(wù)器端第一次獲取Session 則向客戶端設(shè)置Set-Cookie 
request.getSession(false)//如果請求包的cookie帶了JsessionID,則獲取;如果沒帶來sessionid則返回null 且不創(chuàng)建session對象!
request.getSession(true)//有session則得到session,沒有則用Set-cookie設(shè)置到瀏覽器
request.getSession()//和上一個方法效果相同

任何JSP頁面,都會自動創(chuàng)建session!

HttpSession其他方法

  • String getId()
    • 獲取sessionId
  • void invalidate()
    • 調(diào)用這個方法會使session讓當(dāng)前session失效!當(dāng)session失效后,客戶端再次請求,服務(wù)器會給客戶端創(chuàng)建一個新的session在響應(yīng)中給客戶端Set-Cookie 新sessionId
  • boolean isNew()
    • 查看session是否為“New”。當(dāng)客戶端第一次請求時,服務(wù)器為客戶端創(chuàng)建session,但這時服務(wù)器還沒有響應(yīng)客戶端(還沒有發(fā)送響應(yīng)包Set-Cookie:sessionId),此時session的狀態(tài)為“New”
  • long getCreationTime():返回session的創(chuàng)建時間,返回值為當(dāng)前時間的毫秒值;
  • long getLastAccessedTime():返回session的最后活動時間,返回值為當(dāng)前時間的毫秒值;
  • int getMaxInactiveInterval()
    • 獲取session可以的最大不活動時間(秒),默認(rèn)為30分鐘。當(dāng)session在30分鐘內(nèi)沒有使用,那么Tomcat會在session池中移除這個session;
  • void setMaxInactiveInterval(int interval):設(shè)置session允許的最大不活動時間(秒),如果設(shè)置為1秒,那么只要session在1秒內(nèi)不被使用,那么session就會被移除;
request.getSession().isNew();

web.xml中配置session的最大不活動時間(分鐘數(shù))
    <session-config>
        <session-timeout>30</session-timeout>
    </session-config>

URL重寫(理解)

HttpSession底層依賴CookieURL重寫!

session依賴Cookie,目的是讓客戶端發(fā)出請求時帶上Cookie(含有sessionId),服務(wù)器才能找到對應(yīng)的session
如果瀏覽器禁用所有cookie,所以服務(wù)器給瀏覽器Set-Cookie多少遍都沒用。只能用URL重寫:
讓網(wǎng)站的所有超鏈接(get)、表單(post)中都添加一個名為JSESSIONID的參數(shù),這樣服務(wù)器通過獲取請求參數(shù)也能得到sessionId,從而找到session對象。

URL重寫,簡單說實質(zhì):就是把所有的頁面中的路徑,都使用這條語句處理一下:
response.encodeURL(String url)

該方法會對url進行智能的重寫:
當(dāng)瀏覽器不支持cookie或支持Cookie但第一次請求時,request中的Cookie沒有帶sessionid,則response.encodeURL()方法會在URL后追加sessionId(比如首次訪問JSP頁面)
當(dāng)request中的Cookie帶sessionid時,response.encodeURL()方法不會在URL后追加sessionId

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容