本文目錄:
- JSP基礎(chǔ)
- Cookie
- HttpSession
JSP基礎(chǔ)
JSP(Java Server Pages)是JavaWeb服務(wù)器端的動(dòng)態(tài)資源送爸。它與html頁(yè)面的作用是相同的袭厂,顯示數(shù)據(jù)和獲取數(shù)據(jù)纹磺。
jsp和Servlet的常見分工
(jsp) request -- servlet -- (jsp) response
- JSP
- 作為請(qǐng)求發(fā)起頁(yè)面橄杨,把來(lái)自用戶的post/get等請(qǐng)求發(fā)送給servlet:例如頁(yè)面內(nèi)含有表單、超鏈接
- 作為請(qǐng)求結(jié)束頁(yè)面,接受servlet的數(shù)據(jù)役耕,顯示給用戶瞬痘。
- Servlet
- 獲取jsp發(fā)送來(lái)的請(qǐng)求參數(shù)
- 處理請(qǐng)求图云,得到處理后的數(shù)據(jù)
- 把結(jié)果保存到request中
- 轉(zhuǎn)發(fā)到顯示結(jié)果的JSP
jsp的作用
- Servlet
- 優(yōu)點(diǎn):動(dòng)態(tài)資源(html靜態(tài)頁(yè)面不能包含動(dòng)態(tài)信息)
- 缺點(diǎn):不適合設(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動(dòng)作元素<jsp: />
-
jsp的9大內(nèi)置對(duì)象(無(wú)需創(chuàng)建即可使用的對(duì)象):
- request
- response
- out
- session
- application 和tomcat進(jìn)程“共生死”
- pageContext
- config
- page
- exception
3種java腳本
<% java代碼片段 %>
<!--,常用
可寫0到n條Java語(yǔ)句
方法內(nèi)能寫什么晒哄,它就可以寫什么
-->
<%=表達(dá)式 %>
<!--java表達(dá)式寝凌,用于輸出一條表達(dá)式(或變量)的結(jié)果较木。-->
response.getWriter().print( ... );
<!--這里能放什么伐债,它就可以放什么致开!
比如某個(gè)具有返回值的函數(shù) func1()
-->
<%!聲明 成員變量等 %>
<!--聲明双戳,用來(lái)創(chuàng)建類的成員變量和成員方法(基本不用,但容易被考到)
類體中可以放什么千诬,它就可以放什么耍目!
Class man{
成員變量
成員方法
構(gòu)造器
構(gòu)造代碼塊
靜態(tài)塊
內(nèi)部類
}
-->
out.print()和out.write() 幾乎沒(méi)有區(qū)別:
String s = null;
out.print(s); // outputs the text "null" 處理空指針異常,輸出字符串“null”徐绑。
out.write(s); // NullPointerException 不處理該異常邪驮。
jsp注釋
<%-- 當(dāng)服務(wù)器把jsp編譯成java文件前就沒(méi)有這些注釋了! --%>
<!-- html注釋會(huì)發(fā)到客戶端瀏覽器傲茄。 -->
案例:演示jsp中java腳本的使用毅访!
案例:演示jsp與servlet分工!
jsp原理(理解)
- 當(dāng)jsp頁(yè)面第一次被訪問(wèn)時(shí):
- 1.服務(wù)器會(huì)把jsp編譯成java文件(這個(gè)java其實(shí)是一個(gè)servlet類)
- 2.再把java編譯成.class
- 3.創(chuàng)建該類對(duì)象
- 4.最后調(diào)用它的service()方法
- 第二次請(qǐng)求某jsp時(shí)喻粹,直接調(diào)用service()方法。
jsp實(shí)質(zhì)是一種特殊的Servlet
在tomcat/work/Catalina目錄下可以找到 jsp 對(duì)應(yīng)的 .java 源代碼,和生成的.class文件草巡。
- 查看jsp對(duì)應(yīng)java文件:
- .java語(yǔ)句守呜,方法體的最上面,聲明了9大內(nèi)置對(duì)象山憨,賦值查乒。
- 原封不動(dòng)的把程序員寫的代碼放到方法體下面。
- html語(yǔ)句郁竟,全是這樣輸出的:
out.wirte("字符串");
Cookie
Http協(xié)議與Cookie
- Cookie是HTTP協(xié)議制定的玛迄!
服務(wù)器保存Cookie到瀏覽器,再下次瀏覽器請(qǐng)求服務(wù)器時(shí)棚亩,會(huì)帶上Cookie - 由服務(wù)器創(chuàng)建保存到客戶端瀏覽器的一個(gè)鍵值對(duì)蓖议!
”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ù)器時(shí),會(huì)帶上Cookie:
Cookie: aaa=AAA; bbb=BBB
- Http協(xié)議規(guī)定(很多瀏覽器都會(huì)在一定范圍內(nèi)違反HTTP規(guī)定)
- 1個(gè)Cookie最大4KB
- 1個(gè)服務(wù)器最多向1個(gè)瀏覽器保存20個(gè)Cookie
- 1個(gè)瀏覽器最多可以保存300個(gè)Cookie
Cookie的用途
注意Cookie不跨瀏覽器讥蟆!
- 跟蹤客戶端狀態(tài)
- 保存購(gòu)物車信息
- 只保存上次的登錄名拒担,方便登錄。
JavaWeb中使用Cookie
- 原始方式(了解)
- 使用response發(fā)送Set-Cookie響應(yīng)頭
- 使用request獲取Cookie請(qǐng)求頭
- 便捷方式(重要9パ)
repsonse.addCookie()//讓瀏覽器端保存Cookie
request.getCookies()//獲取瀏覽器端帶來(lái)的Cookie
//如果HTTP請(qǐng)求沒(méi)有帶來(lái)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ù)器時(shí)钧栖,http請(qǐng)求包頭里面有Cookie頭,格式如下:
Cookie: key1=value1; key2=value2; key3=value3
Cookie詳解
- Cookie不只有name和value兩個(gè)屬性
- Cookie的maxAge
- maxAge>0:Cookie的最大生命婆翔。瀏覽器會(huì)把Cookie保存到客戶機(jī)硬盤上拯杠,有效時(shí)長(zhǎng)為maxAge的值,以秒為單位啃奴。
cookie.setMaxAge(60)
- maxAge<0:Cookie只在瀏覽器內(nèi)存中存在(瀏覽器進(jìn)程結(jié)束潭陪,Cookie消失)
- maxAge=0:立即刪除同名cookie
- maxAge>0:Cookie的最大生命婆翔。瀏覽器會(huì)把Cookie保存到客戶機(jī)硬盤上拯杠,有效時(shí)長(zhǎng)為maxAge的值,以秒為單位啃奴。
- Cookie的path
- Cookie的path決定:當(dāng)瀏覽器訪問(wèn)服務(wù)器某個(gè)路徑時(shí),帶上哪些Cookie
- Cookie的path不可能是設(shè)置這個(gè)Cookie在客戶端的保存路徑!
- Cookie的path由響應(yīng)包response創(chuàng)建Cookie時(shí)設(shè)置
- 瀏覽器訪問(wèn)服務(wù)器的路徑依溯,如果包含某個(gè)Cookie的路徑老厌,那么就會(huì)帶上這個(gè)Cookie。
例如:服務(wù)器端設(shè)置
aCookie.path=/day11_1/;
bCookie.path=/day11_1/aaa/;
cCookie.path=/day11_1/aaa/bbb/;
客戶端瀏覽器
訪問(wèn):域名/day11_1/anyname.jsp 時(shí)帶上aCookie
訪問(wèn):域名/day11_1/aaa/anyname.jsp 時(shí)帶上aCookie黎炉、bCookie
訪問(wèn):域名/day11_1/aaa/bbb/anyname.jsp 時(shí)帶上aCookie枝秤、bCookie、cCookie
- Cookie的path默認(rèn)值:當(dāng)前訪問(wèn)路徑的父路徑慷嗜。
如訪問(wèn)/day11_1/jsps/a.jsp時(shí)響應(yīng)包設(shè)置了cookie淀弹,該cookie的默認(rèn)path為/day11_1/jsps/
- Cookie的domain用來(lái)指定服務(wù)器設(shè)置的Cookie給哪些域名!當(dāng)多個(gè)二級(jí)域中共享Cookie時(shí)才需要用
例如這些二級(jí)域名之間需要共享cookie:www.baidu.com庆械、zhidao.baidu.com薇溃、news.baidu.com、tieba.baidu.com
服務(wù)器端:
cookie.setDomain(".baidu.com");//設(shè)置domain 直接省略掉二級(jí)域名的不同之處
cookie.setPath("/");//設(shè)置path
- 自己測(cè)試,步驟:
修改本機(jī)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兩個(gè)目錄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(重點(diǎn))
HttpSession概述
HttpSession是由JavaWeb提供的,用來(lái)會(huì)話跟蹤的類忿峻。session是服務(wù)器端對(duì)象薄啥,保存在服務(wù)器端!9渖小垄惧!
HttpSession底層依賴Cookie或URL重寫!
HttpSession是Servlet三大域?qū)ο笾?/p>
三大域?qū)ο?/p>
-
request
- 每一次請(qǐng)求都會(huì)創(chuàng)建一個(gè)request
- 請(qǐng)求鏈共享數(shù)據(jù) 可把request發(fā)給多個(gè)Servlet
-
session
- 會(huì)話是同一個(gè)用戶在瀏覽器打開后關(guān)閉前對(duì)服務(wù)器的多次請(qǐng)求绰寞。
-
application(ServletContext)
- 程序存在到逊,保存在這里的內(nèi)容就一直存在
三大域?qū)ο蠖加蟹椒ǎ?/p>
void setAttribute(String name, Object value);
Object getAttribute(String name);
void removeAttribute(String name);
session是域?qū)ο螅杂衧etAttribute()和getAttribute()等方法
服務(wù)器會(huì)為每個(gè)會(huì)話創(chuàng)建一個(gè)session對(duì)象滤钱,所以session中的數(shù)據(jù)可供當(dāng)前會(huì)話中所有servlet共享觉壶。
會(huì)話 會(huì)話追蹤
- 會(huì)話:同一個(gè)用戶在瀏覽器打開后關(guān)閉前對(duì)服務(wù)器的多次請(qǐng)求。
- 會(huì)話范圍:某個(gè)用戶從首次訪問(wèn)服務(wù)器開始件缸,到該用戶關(guān)閉瀏覽器結(jié)束铜靶!
- 會(huì)話方便了服務(wù)器端共享數(shù)據(jù)!對(duì)客戶端瀏覽器只在Cookie里只有一個(gè)session的ID他炊,服務(wù)器端在這個(gè)session中設(shè)置的一些值對(duì)用戶均不可見争剿。
- 會(huì)話跟蹤技術(shù):在一次會(huì)話中共享數(shù)據(jù)。
HTTP是無(wú)狀態(tài)協(xié)議痊末,每個(gè)請(qǐng)求之間無(wú)法共享數(shù)據(jù)蚕苇。這就無(wú)法知道會(huì)話什么時(shí)候開始,什么時(shí)候結(jié)束凿叠,也無(wú)法確定發(fā)出請(qǐng)求的用戶身份涩笤。這說(shuō)明需要使用額外的手段來(lái)跟蹤會(huì)話嚼吞! - session緩存:服務(wù)器會(huì)為每個(gè)客戶端創(chuàng)建一個(gè)session對(duì)象,session就好比客戶在服務(wù)器端的賬戶蹬碧,它們被服務(wù)器保存到一個(gè)Map中舱禽,這個(gè)Map被稱之為session緩存!
Servlet中得到session對(duì)象
HttpSession session = request.getSession();
Jsp中得到session對(duì)象
session是jsp內(nèi)置對(duì)象,不用創(chuàng)建,直接使用锰茉!如
<%session.setAttribute("aa","bb")%>
案例1:session 多次請(qǐng)求中共享數(shù)據(jù)
- AServlet:向session域中保存數(shù)據(jù)
- BServlet:從session域中獲取數(shù)據(jù)
- 演示:
第一個(gè)請(qǐng)求:訪問(wèn)AServlet
第二個(gè)請(qǐng)求:訪問(wèn)BServlet
案例2:session 保存用戶登錄信息(精通)
-
案例相關(guān)頁(yè)面和Servlet:
- login.jsp:登錄頁(yè)面
- succ1.jsp:只有登錄成功才能訪問(wèn)的頁(yè)面
- succ2.jsp:只有登錄成功才能訪問(wèn)的頁(yè)面
- LoginServlet:校驗(yàn)用戶是否登錄成功呢蔫!
-
各頁(yè)面和Servlet內(nèi)容:
- login.jsp:提供登錄表單,提交表單請(qǐng)求LoginServlet
- LoginServlet:獲取請(qǐng)求參數(shù)飒筑,校驗(yàn)用戶是否登錄成功
- 失斊酢:保存錯(cuò)誤信息到request域,轉(zhuǎn)發(fā)到login.jsp(login.jsp顯示request域中的錯(cuò)誤信息)
- 成功:保存用戶信息到session域中协屡,重定向到succ1.jsp頁(yè)面俏脊,顯示session域中的用戶信息
- succ1.jsp:從session域獲取用戶信息,如果不存在肤晓,顯示“您還沒(méi)有登錄”爷贫。存在則顯示用戶信息
- succ2.jsp:從session域獲取用戶信息,如果不存在补憾,顯示“您還沒(méi)有登錄”漫萄。存在則顯示用戶信息
只要用戶沒(méi)有關(guān)閉瀏覽器,session就一直存在盈匾,那么保存在session中的用戶信息也就一起存在腾务!那么用戶訪問(wèn)succ1和succ2就會(huì)通過(guò)!
HttpSession原理(理解)
-
request.getSession()方法
- 獲取Cookie中的JSESSIONID(唯一標(biāo)識(shí))
- 如果Cookie中沒(méi)有sessionId削饵,從url參數(shù)中獲取 格式為;JsessionID=也沒(méi)有時(shí)岩瘦,服務(wù)器創(chuàng)建一個(gè)session并保存,把新創(chuàng)建的sessionId設(shè)置到瀏覽器Cookie中窿撬,這個(gè)Cookie的生命為-1启昧,即只在瀏覽器內(nèi)存中存在!
- 關(guān)閉瀏覽器前劈伴,再次請(qǐng)求密末,服務(wù)器端執(zhí)行request.getSession()方法,通過(guò)客戶端帶Cookie的請(qǐng)求跛璧,得到Cookie中的sessionId严里,服務(wù)器的session對(duì)象與上一次請(qǐng)求使用的是同一session對(duì)象。
- 如果sessionId存在赡模,但通過(guò)sessionId沒(méi)有找到session對(duì)象(可能超時(shí)被服務(wù)器刪除了),創(chuàng)建session保存到服務(wù)器师抄,把新創(chuàng)建的sessionId保存到客戶端瀏覽器的Cookie中
- 如果sessionId存在漓柑,通過(guò)sessionId查找到了session對(duì)象(不會(huì)再創(chuàng)建新session對(duì)象)
服務(wù)器不會(huì)馬上給用戶創(chuàng)建session,在第一次獲取session時(shí)才會(huì)創(chuàng)建該用戶的session!
session對(duì)象是保存在服務(wù)器端的辆布,而sessionId是通過(guò)Cookie保存在客戶端的瞬矩。
因?yàn)镃ookie不能在多個(gè)瀏覽器中共享,所以session也不能在多個(gè)瀏覽器中共享锋玲。
//以下都是Servlet的代碼:
//所有Servlet如果不寫這一行景用,都不會(huì)自動(dòng)創(chuàng)建session(不會(huì)給客戶端Set-Cookie)
request.getSession();//如果是服務(wù)器端第一次獲取Session 則向客戶端設(shè)置Set-Cookie
request.getSession(false)//如果請(qǐng)求包的cookie帶了JsessionID菩鲜,則獲嚷癯辍;如果沒(méi)帶來(lái)sessionid則返回null 且不創(chuàng)建session對(duì)象艇纺!
request.getSession(true)//有session則得到session盾碗,沒(méi)有則用Set-cookie設(shè)置到瀏覽器
request.getSession()//和上一個(gè)方法效果相同
任何JSP頁(yè)面媚污,都會(huì)自動(dòng)創(chuàng)建session!
HttpSession其他方法
- String getId()
- 獲取sessionId
- void invalidate()
- 調(diào)用這個(gè)方法會(huì)使session讓當(dāng)前session失效!當(dāng)session失效后廷雅,客戶端再次請(qǐng)求耗美,服務(wù)器會(huì)給客戶端創(chuàng)建一個(gè)新的session在響應(yīng)中給客戶端Set-Cookie 新sessionId
- boolean isNew()
- 查看session是否為“New”。當(dāng)客戶端第一次請(qǐng)求時(shí)航缀,服務(wù)器為客戶端創(chuàng)建session商架,但這時(shí)服務(wù)器還沒(méi)有響應(yīng)客戶端(還沒(méi)有發(fā)送響應(yīng)包Set-Cookie:sessionId),此時(shí)session的狀態(tài)為“New”
- long getCreationTime():返回session的創(chuàng)建時(shí)間芥玉,返回值為當(dāng)前時(shí)間的毫秒值蛇摸;
- long getLastAccessedTime():返回session的最后活動(dòng)時(shí)間,返回值為當(dāng)前時(shí)間的毫秒值飞傀;
- int getMaxInactiveInterval()
- 獲取session可以的最大不活動(dòng)時(shí)間(秒)皇型,默認(rèn)為30分鐘。當(dāng)session在30分鐘內(nèi)沒(méi)有使用砸烦,那么Tomcat會(huì)在session池中移除這個(gè)session弃鸦;
- void setMaxInactiveInterval(int interval):設(shè)置session允許的最大不活動(dòng)時(shí)間(秒),如果設(shè)置為1秒幢痘,那么只要session在1秒內(nèi)不被使用唬格,那么session就會(huì)被移除;
request.getSession().isNew();
web.xml中配置session的最大不活動(dòng)時(shí)間(分鐘數(shù))
<session-config>
<session-timeout>30</session-timeout>
</session-config>
URL重寫(理解)
HttpSession底層依賴Cookie或URL重寫颜说!
session依賴Cookie购岗,目的是讓客戶端發(fā)出請(qǐng)求時(shí)帶上Cookie(含有sessionId),服務(wù)器才能找到對(duì)應(yīng)的session
如果瀏覽器禁用所有cookie门粪,所以服務(wù)器給瀏覽器Set-Cookie多少遍都沒(méi)用喊积。只能用URL重寫:
讓網(wǎng)站的所有超鏈接(get)、表單(post)中都添加一個(gè)名為JSESSIONID的參數(shù)玄妈,這樣服務(wù)器通過(guò)獲取請(qǐng)求參數(shù)也能得到sessionId乾吻,從而找到session對(duì)象髓梅。
URL重寫,簡(jiǎn)單說(shuō)實(shí)質(zhì):就是把所有的頁(yè)面中的路徑绎签,都使用這條語(yǔ)句處理一下:
response.encodeURL(String url)
該方法會(huì)對(duì)url進(jìn)行智能的重寫:
當(dāng)瀏覽器不支持cookie或支持Cookie但第一次請(qǐng)求時(shí)枯饿,request中的Cookie沒(méi)有帶sessionid,則response.encodeURL()方法會(huì)在URL后追加sessionId(比如首次訪問(wèn)JSP頁(yè)面)
當(dāng)request中的Cookie帶sessionid時(shí)诡必,response.encodeURL()方法不會(huì)在URL后追加sessionId