request和response
1.1 重定向
特點(diǎn): 1,重定向是客戶端行為裙盾。 2实胸,重定向是瀏覽器做了至少兩次的訪問請(qǐng)求。 3番官,重定向?yàn)g覽器地址改變庐完。 4,重定向兩次跳轉(zhuǎn)之間傳輸?shù)男畔?huì)丟失(request范圍)徘熔。 5门躯,重定向可以指向任何的資源,包括當(dāng)前應(yīng)用程序中的其他資源酷师,同一個(gè)站點(diǎn)上的其他應(yīng)用程序中的資源生音,其他站點(diǎn) 的資源。注意:傳遞給HttpServletResponse.sendRedirect 方法的相對(duì)URL以“/”開頭窒升,它是相對(duì)于整個(gè)WEB 站點(diǎn)的根目錄
請(qǐng)求轉(zhuǎn)發(fā)
1缀遍,轉(zhuǎn)發(fā)是服務(wù)器行為 2,轉(zhuǎn)發(fā)是瀏覽器只做了一次訪問請(qǐng)求 3饱须,轉(zhuǎn)發(fā)瀏覽器地址不變 4域醇,轉(zhuǎn)發(fā)兩次跳轉(zhuǎn)之間傳輸?shù)男畔⒉粫?huì)丟失,所以可以通過request進(jìn)行數(shù)據(jù)的傳遞 5蓉媳,轉(zhuǎn)發(fā)只能將請(qǐng)求轉(zhuǎn)發(fā)給同一個(gè)WEB應(yīng)用中的組件 注意:如果創(chuàng)建RequestDispatcher 對(duì)象時(shí)指定的相對(duì)URL以“/”開頭譬挚,它是相對(duì)于當(dāng)前WEB應(yīng)用程序的根目錄。
ServletResponse簡(jiǎn)介
? ? ? 定義輔助 servlet 將響應(yīng)發(fā)送到客戶端的對(duì)象酪呻。servlet 容器創(chuàng)建 ServletResponse 對(duì)象减宣,并將它作為 參數(shù)傳遞給 servlet 的 service 方法。 要發(fā)送 MIME 正文響應(yīng)中的二進(jìn)制數(shù)據(jù)玩荠,請(qǐng)使用 getOutputStream 返回的 ServletOutputStream漆腌。要發(fā)送字符數(shù)據(jù),請(qǐng)使用 getWriter 返回的 PrintWriter 對(duì)象阶冈。
?HttpServletResponse介紹
擴(kuò)展 ServletResponse 接口以提供特定于 HTTP 的發(fā)送響應(yīng)功能闷尿。例如,該接口擁有訪問 HTTP 頭和 cookie 的方法女坑。 客戶端向服務(wù)器發(fā)起的都是HTTP協(xié)議操作,所以我們大部分使用HttpServletResponse對(duì) 象作為直接操作對(duì)象!
HttpServletRequest介紹
HttpServletRequest對(duì)象代表客戶端的請(qǐng)求填具,當(dāng)客戶端通過HTTP協(xié)議訪問服務(wù)器時(shí),HTTP請(qǐng)求頭中的所 有信息都封裝在這個(gè)對(duì)象中匆骗,開發(fā)人員通過這個(gè)對(duì)象的方法劳景,可以獲得客戶這些信息誉简。
同響應(yīng)相同,客戶端請(qǐng)求協(xié)議都是基于HTTP所以我們選用HttpServletRequest來操作用戶發(fā)送過來 的請(qǐng)求的數(shù)據(jù)!
HttpServletRequest常用API
URL :Uniform Resource Location (統(tǒng)一資源定位符) 網(wǎng)址
URI :Uniform Resource Identifier (統(tǒng)一資源標(biāo)識(shí)符)? URI包含URL
//獲取請(qǐng)求路徑相關(guān)參數(shù) **?
getRequestURL方法返回客戶端發(fā)出請(qǐng)求時(shí)的完整URL。
?getRequestURI方法返回請(qǐng)求行中的資源名部分盟广。
?getQueryString 方法返回請(qǐng)求行中的參數(shù)部分闷串。
?getRemoteAddr方法返回發(fā)出請(qǐng)求的客戶機(jī)的IP地址
?getRemoteHost方法返回發(fā)出請(qǐng)求的客戶機(jī)的完整主機(jī)名?
getRemotePort方法返回客戶機(jī)所使用的網(wǎng)絡(luò)端口號(hào)?
getLocalAddr方法返回WEB服務(wù)器的IP地址。
?getLocalName方法返回WEB服務(wù)器的主機(jī)名 getMethod得到客戶機(jī)請(qǐng)求方式
封裝請(qǐng)求參數(shù)
第一種方式:使用getParameter獲取
使用Apache BeanUtils進(jìn)行快速映射
BeanUtils.populate(bean2, request.getParameterMap());
總 結(jié)
1頁面跳轉(zhuǎn)
重定向
? 1衡蚂,重定向是客戶端行為窿克。
? 2,重定向是瀏覽器做了至少兩次的訪問請(qǐng)求毛甲。
? 3年叮,重定向?yàn)g覽器地址改變。
? 4玻募,重定向兩次跳轉(zhuǎn)之間傳輸?shù)男畔?huì)丟失(request范圍)只损。
? 5,重定向可以指向任何的資源七咧,包括當(dāng)前應(yīng)用程序中的其他資源跃惫,同一個(gè)站點(diǎn)上的其他應(yīng)用程序中 的資源蕉鸳,其他站點(diǎn)的資源蠢涝。注意:傳遞給HttpServletResponse.sendRedirect 方法的相對(duì)URL以“/”開頭, 它是相對(duì)于整個(gè)WEB站點(diǎn)的根目錄
response.sendRedirect("");
轉(zhuǎn)發(fā)
? 1护姆,轉(zhuǎn)發(fā)是服務(wù)器行為
? 2蝗砾,轉(zhuǎn)發(fā)是瀏覽器只做了一次訪問請(qǐng)求
? 3先较,轉(zhuǎn)發(fā)瀏覽器地址不變
? 4,轉(zhuǎn)發(fā)兩次跳轉(zhuǎn)之間傳輸?shù)男畔⒉粫?huì)丟失悼粮,所以可以通過request進(jìn)行數(shù)據(jù)的傳遞
? 5闲勺,轉(zhuǎn)發(fā)只能將請(qǐng)求轉(zhuǎn)發(fā)給同一個(gè)WEB應(yīng)用中的組件 注意:如果創(chuàng)建RequestDispatcher 對(duì)象時(shí)指定的相對(duì)URL以“/”開頭,它是相對(duì)于當(dāng)前WEB應(yīng)用程序的根 目錄扣猫。
request.getRequestDispatcher("").forward(request,response);
2 response對(duì)象
ServletResponse
? setCharacterEncoding();
? setConentType();
HttpServletResponse extends ServletResponse
? addCookie();
? addHeader();
3 request對(duì)象
ServletRequest
? setChracterEncoding();
? getRequestURL();
? getRequestURI();
HttpServletRequest
? getHeader()
? getParameter();
Cookie是瀏覽器的一片存儲(chǔ)區(qū)域,可以以key-value的形式來存儲(chǔ)一些值
Cookie是在瀏覽器訪問WEB服務(wù)器的某個(gè)資源時(shí)菜循,由WEB服務(wù)器在HTTP響應(yīng)消息頭中附帶傳送給瀏覽器的一片數(shù)據(jù),WEB服務(wù)器傳送給各個(gè)客戶端瀏覽器的數(shù)據(jù)是可以各不相同的
一旦WEB瀏覽器保存了某個(gè)Cookie申尤,那么它在以后每次訪問該WEB服務(wù)器時(shí)癌幕,都應(yīng)在HTTP請(qǐng)求頭中將這個(gè)Cookie回傳給WEB服務(wù)器。
WEB服務(wù)器通過在HTTP響應(yīng)消息中增加Set-Cookie響應(yīng)頭字段將Cookie信息發(fā)送給瀏覽器瀑凝,瀏覽器則通過在HTTP請(qǐng)求消息中增加Cookie請(qǐng)求頭字段將Cookie回傳給WEB服務(wù)器
一個(gè)Cookie只能標(biāo)識(shí)一種信息序芦,它至少含有一個(gè)標(biāo)識(shí)該信息的名稱(NAME)和設(shè)置值(VALUE)
一個(gè)WEB站點(diǎn)可以給一個(gè)WEB瀏覽器發(fā)送多個(gè)Cookie,一個(gè)WEB瀏覽器也可以存儲(chǔ)多個(gè)WEB站點(diǎn)提供的Cookie
瀏覽器一般只允許存放300個(gè)Cookie粤咪,每個(gè)站點(diǎn)最多存放20個(gè)Cookie,每個(gè)Cookie的大小限制為4KB
創(chuàng)建Cookie
Cookie ck=new Cookie("code", code);
ck.setPath("/");//設(shè)置Cookie的路徑
ck.setMaxAge(-1);//內(nèi)存存儲(chǔ)渴杆,取值有三種:>0有效期寥枝,單位秒宪塔;=0失效;<0內(nèi)存存儲(chǔ)
response.addCookie(ck);//讓瀏覽器添加Cookie
Cookie的優(yōu)缺點(diǎn)
優(yōu)點(diǎn):
可配置到期規(guī)則 Cookie 可以在瀏覽器會(huì)話結(jié)束時(shí)到期囊拜,或者可以在客戶端計(jì)算機(jī)上無限期存在某筐,這取決于客戶端的到期規(guī)則。不需要任何服務(wù)器資源 Cookie 存儲(chǔ)在客戶端并在發(fā)送后由服務(wù)器讀取冠跷。簡(jiǎn)單性 Cookie 是一種基于文本的輕量結(jié)構(gòu)南誊,包含簡(jiǎn)單的鍵值對(duì)。數(shù)據(jù)持久性 雖然客戶端計(jì)算機(jī)上 Cookie 的持續(xù)時(shí)間取決于客戶端上的 Cookie 過期處理和用戶干預(yù)蜜托,Cookie 通常是客戶端上持續(xù)時(shí)間最長的數(shù)據(jù)保留形式
缺點(diǎn):
大小受到限制 大多數(shù)瀏覽器對(duì) Cookie 的大小有 4096 字節(jié)的限制抄囚,盡管在當(dāng)今新的瀏覽器和客戶端設(shè)備版本中,支持 8192 字節(jié)的 Cookie 大小已愈發(fā)常見橄务。用戶配置為禁用 有些用戶禁用了瀏覽器或客戶端設(shè)備接收 Cookie 的能力幔托,因此限制了這一功能。潛在的安全風(fēng)險(xiǎn) Cookie 可能會(huì)被篡改蜂挪。用戶可能會(huì)操縱其計(jì)算機(jī)上的 Cookie重挑,這意味著會(huì)對(duì)安全性造成潛在風(fēng)險(xiǎn)或者導(dǎo)致依賴于 Cookie 的應(yīng)用程序失敗。另外棠涮,雖然 Cookie 只能被將它們發(fā)送到客戶端的域訪問谬哀,歷史上黑客已經(jīng)發(fā)現(xiàn)從用戶計(jì)算機(jī)上的其他域訪問 Cookie 的方法。您可以手動(dòng)加密和解密 Cookie严肪,但這需要額外的編碼史煎,并且因?yàn)榧用芎徒饷苄枰馁M(fèi)一定的時(shí)間而影響應(yīng)用程序的性能
自動(dòng)登錄
/從session中獲取登錄標(biāo)志
? ? ? ? Object obj = req.getSession().getAttribute("login");
? ? ? ? //如果登錄標(biāo)志存在,說明用戶已經(jīng)登錄過了
? ? ? ? if(obj!=null){
? ? ? ? ? ? req.getRequestDispatcher("/WEB-INF/pages/userinfo.html").forward(req,resp);
? ? ? ? }else{
? ? ? ? ? ? //做自動(dòng)登錄
? ? ? ? ? ? Cookie[] cookies = req.getCookies();
? ? ? ? ? ? for (Cookie cookie : cookies) {
? ? ? ? ? ? ? ? String name = cookie.getName();
? ? ? ? ? ? ? ? if("autologin".equals(name)){
? ? ? ? ? ? ? ? ? ? String value = cookie.getValue();
? ? ? ? ? ? ? ? ? ? String[] strs = value.split("=");
? ? ? ? ? ? ? ? ? ? if(Message.users.containsKey(strs[0])&&Message.users.get(strs[0]).equals(strs[1])){
? ? ? ? ? ? ? ? ? ? ? ? req.getSession().setAttribute("login",true);
? ? ? ? ? ? ? ? ? ? ? ? req.getRequestDispatcher("/WEB-INF/pages/userinfo.html").forward(req,resp);
? ? ? ? ? ? ? ? ? ? ? ? return;
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
Session
定義
Session可以讓服務(wù)器確認(rèn)多個(gè)請(qǐng)求是否來自于同一個(gè)瀏覽器
Session用于跟蹤客戶的狀態(tài)
Session指的是在一段時(shí)間內(nèi),單個(gè)客戶與Web服務(wù)器的一連串相關(guān)的交互過程诬垂。在一個(gè)Session中劲室,客戶可能會(huì)多次請(qǐng)求訪問同一個(gè)網(wǎng)頁,也有可能請(qǐng)求訪問各種不同的服務(wù)器資源
session被用于表示一個(gè)持續(xù)的連接狀態(tài)结窘,在網(wǎng)站訪問中一般指代客戶端瀏覽器的進(jìn)程從開啟到結(jié)束的過程很洋。session其實(shí)就是網(wǎng)站分析的訪問(visits)度量,表示一個(gè)訪問的過程
session的常見實(shí)現(xiàn)形式是會(huì)話cookie(session cookie)隧枫,即未設(shè)置過期時(shí)間的cookie喉磁,這個(gè)cookie的默認(rèn)生命周期為瀏覽器會(huì)話期間,只要關(guān)閉瀏覽器窗口官脓,cookie就消失了协怒。實(shí)現(xiàn)機(jī)制是當(dāng)用戶發(fā)起一個(gè)請(qǐng)求的時(shí)候,服務(wù)器會(huì)檢查該請(qǐng)求中是否包含sessionid卑笨,如果未包含孕暇,則系統(tǒng)會(huì)創(chuàng)造一個(gè)名為JSESSIONID的輸出 cookie返回給瀏覽器(只放入內(nèi)存,并不存在硬盤中),并將其以HashTable的形式寫到服務(wù)器的內(nèi)存里面妖滔;當(dāng)已經(jīng)包含sessionid是隧哮,服務(wù)端會(huì)檢查找到與該session相匹配的信息,如果存在則直接使用該sessionid座舍,若不存在則重新生成新的 session沮翔。這里需要注意的是session始終是有服務(wù)端創(chuàng)建的,并非瀏覽器自己生成的曲秉〔墒矗 但是瀏覽器的cookie被禁止后session就需要用get方法的URL重寫的機(jī)制或使用POST方法提交隱藏表單的形式來實(shí)現(xiàn)
獲取Session
HttpSession session=request.getSession();
存儲(chǔ)和刪除Session中的值
使用HttpSession的setAttrobute(屬性名,Object)方法
獲取HttpSession的getAttribute(屬性名)
刪除HttpSession的removeAttribute(屬性名)
Session超時(shí)
我們不能無時(shí)間限制的存儲(chǔ)session,這樣做是不安全的
HttpSession的最后一程訪問時(shí)間和當(dāng)前時(shí)間的差距大于了指定的最大空閑時(shí)間,這時(shí)服務(wù)器就會(huì)銷毀Session對(duì)象承二。默認(rèn)的空閑時(shí)間為30分鐘
幾種超時(shí)情況
超過了設(shè)置的超時(shí)時(shí)間
主動(dòng)調(diào)用了invalidate方法
服務(wù)器主動(dòng)或異常關(guān)閉
注意:瀏覽器關(guān)閉并不會(huì)讓Session失效
總結(jié):
Session
可以被同一個(gè)瀏覽器發(fā)出的多個(gè)請(qǐng)求共享
增刪改查 設(shè)置超時(shí)時(shí)間 銷毀session
超時(shí)時(shí)間 :? Java代碼直接 > 項(xiàng)目的web.xml中配置 > tomcat的web.xml中配置(config)
是根據(jù)瀏覽器發(fā)送來的JSESSIONID的cookie來驗(yàn)證的
登錄狀態(tài)保持案例
Cookie
瀏覽器的一個(gè)存儲(chǔ)技術(shù),可以讓瀏覽器幫助我們存儲(chǔ)一些少量的數(shù)據(jù)
組成 : name value path maxAge
name和path相同才認(rèn)定為重復(fù)
url匹配的cookie才會(huì)發(fā)送到服務(wù)器
maxAge :?
負(fù)數(shù) 內(nèi)存存儲(chǔ), 瀏覽器關(guān)閉之后, 消失
0? 立即消失
正數(shù)? 表示具體的時(shí)間, 單位是秒
過濾器
定義
過濾器會(huì)在請(qǐng)求到達(dá)實(shí)際指向目標(biāo)的時(shí)候先截獲到請(qǐng)求, 并且在請(qǐng)求離開目標(biāo)后再次截獲請(qǐng)求
在截獲請(qǐng)求之后,我們可以對(duì)請(qǐng)求中的內(nèi)容作出修改,甚至拒絕請(qǐng)求
Filter是Servlet技術(shù)的核心內(nèi)容, 我們可以利用其完成權(quán)限控制,過濾請(qǐng)求, 壓縮數(shù)據(jù)等等
public class MyFilter implements Filter{
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
//攔截前
chain.doFilter(request, response);
//攔截后
}
}
指定Filter的攔截范圍
配置式
<filter>
? <filter-name>myfilter</filter-name>
? <filter-class>com.qianfeng.user.MyFilter</filter-class>
? </filter>
? <filter-mapping>
? <filter-name>myfilter</filter-name>
? <url-pattern>/*</url-pattern>
? </filter-mapping>
注解式
@WebFilter("/*")
public class MyFilter implements Filter{}
過濾器鏈
通秤苁螅客戶端對(duì)服務(wù)器請(qǐng)求之后,服務(wù)器調(diào)用Servlet之前會(huì)執(zhí)行一組過濾器(多個(gè)過濾器),那么這組過濾器就稱為一條過濾器鏈矢洲。
每個(gè)過濾器實(shí)現(xiàn)某個(gè)特定的功能璧眠,一個(gè)過濾器檢測(cè)多個(gè)Servlet。(匹配幾個(gè)读虏,檢測(cè)幾個(gè))责静。
一組過濾器中的執(zhí)行順序與<filter-mapping>的配置順序呢有關(guān)。當(dāng)?shù)谝粋€(gè)Filter的doFilter方法被調(diào)用時(shí)盖桥,web服務(wù)器會(huì)創(chuàng)建一個(gè)代表Filter鏈的FilterChain對(duì)象傳遞給該方法灾螃。在doFilter方法中,開發(fā)人員如果調(diào)用了FilterChain對(duì)象的doFilter方法揩徊,則web服務(wù)器會(huì)檢查FilterChain對(duì)象中是否還有filter腰鬼,如果有,則調(diào)用第2個(gè)filter塑荒,如果沒有熄赡,則調(diào)用目標(biāo)資源
多過濾器下的優(yōu)先級(jí)
在一個(gè)web應(yīng)用中,可以開發(fā)編寫多個(gè)Filter齿税,這些Filter組合起來稱之為一個(gè)Filter鏈彼硫。web服務(wù)器根據(jù)Filter在web.xml文件中的注冊(cè)順序,決定先調(diào)用哪個(gè)Filter凌箕。原因 : tomcat 讀取web.xml時(shí),是從上往下讀取的, 沒讀取一個(gè)就包裹成Java對(duì)象存入有序集合中
FilterChain對(duì)象傳遞給該方法拧篮。在doFilter方法中,開發(fā)人員如果調(diào)用了FilterChain對(duì)象的doFilter方法牵舱,則web服務(wù)器會(huì)檢查FilterChain對(duì)象中是否還有filter串绩,如果有,則調(diào)用第2個(gè)filter芜壁,如果沒有礁凡,則調(diào)用目標(biāo)資源
如果為注解的話高氮,是按照類名的字符串順序進(jìn)行起作用的
監(jiān)聽器
定義
監(jiān)聽器用于監(jiān)聽web應(yīng)用中某些對(duì)象、信息的創(chuàng)建把篓、銷毀纫溃、增加腰涧,修改韧掩,刪除等動(dòng)作的發(fā)生,然后作出相應(yīng)的響應(yīng)處理窖铡。當(dāng)范圍對(duì)象的狀態(tài)發(fā)生變化的時(shí)候疗锐,服務(wù)器自動(dòng)調(diào)用監(jiān)聽器對(duì)象中的方法。常用于統(tǒng)計(jì)在線人數(shù)和在線用戶费彼,系統(tǒng)加載時(shí)進(jìn)行信息初始化滑臊,統(tǒng)計(jì)網(wǎng)站的訪問量等等
配置
注解式 : @WebServlet
配置式
<listener>
<!--直接寫出自定義的監(jiān)聽器的類名即可-->
? ? <listener-class>com.qf.web.listener.RequestLeftListener</listener-class>
? </listener>
常用的監(jiān)聽器
ServletContextListener : 監(jiān)聽ServletContext生命周期
初始化:contextInitialized
銷毀:contextDestroyed
ServletContextAttributeListener : 監(jiān)聽ServletContext屬性內(nèi)容變化
attributeAdded:監(jiān)聽屬性的添加
attributeRemoved:監(jiān)聽屬性的移除
attributeReplaced:監(jiān)聽屬性的修改
HttpSessionListener : 監(jiān)聽Session生命周期
sessionCreated:監(jiān)聽Session對(duì)象的創(chuàng)建
sessionDestroyed:監(jiān)聽Session對(duì)象的銷毀
HttpSessionAttributeListener : 監(jiān)聽Session屬性內(nèi)容變化
attributeAdded:監(jiān)聽屬性的添加
attributeRemoved:監(jiān)聽屬性的移除
attributeReplaced:監(jiān)聽屬性的修改
HttpSessionActivationListener : 監(jiān)聽服務(wù)器的Session的鈍化和活化
sessionWillPassivate:監(jiān)聽Session內(nèi)部存儲(chǔ)對(duì)象的鈍化-存儲(chǔ)
sessionDidActivate:監(jiān)聽Session內(nèi)部存儲(chǔ)對(duì)象的活化---讀取
對(duì)應(yīng)類需要實(shí)現(xiàn)序列化接口Serializable
HttpSessionBindingListener : 監(jiān)聽Session中對(duì)象的添加和移除(針對(duì)某個(gè)對(duì)象)
valueBound:監(jiān)聽對(duì)象的綁定
valueUnbound:監(jiān)聽對(duì)象的解除綁定
HttpSessionIdListener : 監(jiān)聽HttpSession的id的變化
sessionIdChanged:監(jiān)聽HttpSession的id的變化
ServletRequestListener : 監(jiān)聽request對(duì)象的初始化和銷毀
requestInitialized:監(jiān)聽request對(duì)象的初始化
requestDestroyed:監(jiān)聽request對(duì)象的銷毀
ServletRequestAttributeListener
attributeAdded:監(jiān)聽屬性的添加
attributeRemoved:監(jiān)聽屬性的移除
attributeReplaced:監(jiān)聽屬性的修改
AsyncListener : 監(jiān)聽異步請(qǐng)求
onStartAsync:監(jiān)聽異步開始
onTimeout:監(jiān)聽超時(shí)
onError:監(jiān)聽異步的錯(cuò)誤信息
onComplete:監(jiān)聽異步的完成
總結(jié)
過濾器
所有的請(qǐng)求在到達(dá)目的之前, 要先經(jīng)過過濾器, 請(qǐng)求返回時(shí), 在到達(dá)客戶端之前, 還要經(jīng)過濾器
將多個(gè)servlet中的相同代碼提取出來, 放到監(jiān)聽器中, 以便于提高代碼的復(fù)用性
配置方式
配置文件式(web.xml)
注解式 (@WebFilter("攔截范圍")) wxml
多個(gè)過濾器的順序問題
配置文件式 : 從上往下, 先配置的先執(zhí)行
注解式 : 類名自然順序
url注意事項(xiàng)
/范圍
*.后綴名
Listener
監(jiān)測(cè)
當(dāng)系統(tǒng)中對(duì)應(yīng)的動(dòng)作執(zhí)行時(shí), 相應(yīng)的監(jiān)聽器中的相應(yīng)方法就會(huì)執(zhí)行
優(yōu)點(diǎn) : 非侵入式檢測(cè)