本文目錄:
- JSP基礎(chǔ)
- Cookie
- 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
- maxAge>0:Cookie的最大生命。瀏覽器會把Cookie保存到客戶機硬盤上,有效時長為maxAge的值,以秒為單位。
- 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的domain用來指定服務(wù)器設(shè)置的Cookie給哪些域名!當(dāng)多個二級域中共享Cookie時才需要用
例如這些二級域名之間需要共享cookie:www.baidu.com、zhidao.baidu.com、news.baidu.com、tieba.baidu.com
服務(wù)器端:
cookie.setDomain(".baidu.com");//設(shè)置domain 直接省略掉二級域名的不同之處
cookie.setPath("/");//設(shè)置path
- 自己測試,步驟:
修改本機hosts文件
127.0.0.1 111.x.com
123.0.0.1 222.x.com在${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>把tieba和news兩個目錄copy到${CATALINA_HOME}下
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底層依賴Cookie或URL重寫!
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底層依賴Cookie或URL重寫!
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