一 . Tomcat
1.對Tomcat的理解
Tomcat是一個運行JAVA的網絡服務器,提供能夠讓別人訪問自己寫的頁面的一個程序,是JSP和Serlvet的一個容器。
2.Tomcat的配置
兩種方式,解壓壓縮包(配環境變量)、直接安裝(不用配環境變量);
二 . Http
? ??1.對http協議的理解
????????????超文本傳輸協議,它是TCP/IP協議的一個應用層協議。HTTP協議就是客戶端和服務器? ?交互的一種通迅的格式。
? ??2.http請求
????????2.1請求行
? ??????????????請求行中的GET稱之為請求方式,請求方式有:POST、GET、HEAD、OPTIONS、DELETE、TRACE、PUT
? ??????????????常用的有:POST,GET一般來說,當我們點擊超鏈接,通過地址欄訪問都是get請求方式。通過表單提交的數據一般是post方式。可以簡單理解GET方式用來查詢數據,**POST方式用來提交數據,get的提交速度比post快GET方式:在URL地址后附帶的參數是有限制的,其數據容量通常不能超過1K。POST方式:可以在請求的實體內容中向服務器發送數據,傳送的數據量無限制。
????????2.2請求頭
????????????Accept: text/html,image/* 【瀏覽器告訴服務器,它支持的數據類型】
????????????Accept-Charset: ISO-8859-1 【瀏覽器告訴服務器,它支持哪種字符集】
????????????Accept-Encoding: gzip,compress 【瀏覽器告訴服務器,它支持的壓縮格式】
????????????Accept-Language: en-us,zh-cn 【瀏覽器告訴服務器,它的語言環境】
????????????Host: www.it315.org:80【瀏覽器告訴服務器,它的想訪問哪臺主機】
????????????If-Modified-Since: Tue, 11 Jul 2000 18:23:51 GMT【瀏覽器告訴服務器,緩存數據的時間】
????????????Referer: http://www.it315.org/index.jsp【瀏覽器告訴服務器,客戶機是從那個頁面來的---反盜鏈】
????????????User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)【瀏覽器告訴服務器,瀏覽器的內核是什么】
????????????Cookie【瀏覽器告訴服務器,帶來的Cookie是什么】
????????????Connection: close/Keep-Alive 【瀏覽器告訴服務器,請求完后是斷開鏈接還是保持鏈接】
????????????Date: Tue, 11 Jul 2000 18:23:51 GMT【瀏覽器告訴服務器,請求的時間】
3.http響應(狀態行、響應頭、空行、實體內容)
????3.1狀態行
????3.2響應頭
????????????Location: http://www.it315.org/index.jsp 【服務器告訴瀏覽器要跳轉到哪個頁面】
????????????Server:apache tomcat【服務器告訴瀏覽器,服務器的型號是什么】
????????????Content-Encoding: gzip 【服務器告訴瀏覽器數據壓縮的格式】
????????????Content-Length: 80 【服務器告訴瀏覽器回送數據的長度】
????????????Content-Language: zh-cn 【服務器告訴瀏覽器,服務器的語言環境】
????????????Content-Type: text/html; charset=GB2312 【服務器告訴瀏覽器,回送數據的類型】
????????????Last-Modified: Tue, 11 Jul 2000 18:23:51 GMT【服務器告訴瀏覽器該資源上次更新時間】
????????????Refresh: 1;url=http://www.it315.org【服務器告訴瀏覽器要定時刷新】
????????????Content-Disposition: attachment; filename=aaa.zip【服務器告訴瀏覽器以下載方式打開數據】
????????????Transfer-Encoding: chunked 【服務器告訴瀏覽器數據以分塊方式回送】
????????????Set-Cookie:SS=Q0=5Lb_nQ; path=/search【服務器告訴瀏覽器要保存Cookie】
????????????Expires: -1【服務器告訴瀏覽器不要設置緩存】
????????????Cache-Control: no-cache 【服務器告訴瀏覽器不要設置緩存】
????????????Pragma: no-cache 【服務器告訴瀏覽器不要設置緩存】
????????????Connection: close/Keep-Alive 【服務器告訴瀏覽器連接方式】
????????????Date: Tue, 11 Jul 2000 18:23:51 GMT【服務器告訴瀏覽器回送數據的時間】
三 . Servlet
? ??1.對Serlvet的理解
????????是一個遵循Servlet開發的java類。Serlvet是由服務器調用的,運行在服務器端,能夠處理瀏覽器帶來HTTP請求,并返回一個響應給瀏覽器,從而實現瀏覽器和服務器的交互。
?? ??2.Servlet生命周期
? ??????????加載Servlet。當Tomcat第一次訪問Servlet的時候,Tomcat會負責創建Servlet的實例
? ??????????初始化(init)。當Servlet被實例化后,Tomcat會調用init()方法初始化這個對象
? ??????????處理服務(service)。當瀏覽器訪問Servlet的時候,Servlet會調用service()方法處理請求
? ??????????銷毀。當Tomcat關閉時或者檢測到Servlet要從Tomcat刪除的時候會自動調用destroy()方法,讓該實例釋放掉所占的資源。一個Servlet如果長時間不被使用的話,也會被Tomcat自動銷毀
? ??????????卸載。當Servlet調用完destroy()方法后,等待垃圾回收。如果有需要再次使用這個Servlet,會重新調用init()方法進行初始化操作。
簡單總結:只要訪問Servlet,service()就會被調用。init()只有第一次訪問Servlet的時候才會被調用 ,destroy()只有在Tomcat關閉時調用?。
? ??3.Servlet細節
????????3.1 一個已經注冊的Servlet可以被多次映射(一個servlet 映射到多個URL)
????????3.2 servlet 映射的URL可以使用通配符
????????????*.擴展名 ?(*.jsp ?匹配jsp頁面)//優先級低
????????????正斜杠(/)開頭并以“/*”結尾。(/* 匹配所有界面)
????????3.3 servlet 是單例模式 ?
????????????瀏覽器多次對Servlet的請求,一般情況下,服務器只創建一個Servlet對象,也就是說,Servlet對象一旦創建了,就會駐留在內存中,為后續的請求做服務,直到服務器關閉。
????????3.4 servlet 之間通訊(ServletContext的setAttribute(String name,Object obj)方法)
????4.Servlet之 response ?
????????(HttpServletResponse(封裝http響應的信息))
????????4.1 調用getOutputStream()向瀏覽器輸出數據,輸出二進制格式的數據。
????????????(1)print()不能輸出中文(Tomcat以ISO 8859-1編碼對中文編碼)
????????????(2)輸出中文:response.getOutputStream().write("你好".getBytes());
????????????(3)為了保證通用性,使用UTF-8編碼
????????????//設置頭信息,告訴瀏覽器我回送的數據編碼是utf-8的
?????????????response.setHeader("Content-Type", "text/html;charset=UTF-8");
?????????????response.getOutputStream().write("你好".getBytes("UTF-8"));
? ? ? ? 4.2 調用getWrite() 方法向瀏覽器輸出數據 ,只能輸出字符數據,不能輸出二進制數據。
????????????(1)response.setContentType("text/html;charset=UTF-8");//解決輸出中文亂碼問題
????????4.3?getWriter和getOutputStream細節
????????????(1)getWriter()和getOutputStream()兩個方法不能同時調用。如果同時調用就會出現異常
????????????(2)Servlet的serice()方法結束后【也就是doPost()或者doGet()結束后】,Servlet引擎將檢查getWriter或getOutputStream方法返回的輸出流對象是否已經調用過close方法,如果沒有,Servlet引擎將調用close方法關閉該輸出流對象.
????????4.4?實現文件下載(以下是步驟)
????????????(1)保證站點有此圖片
????????????(2)寫一個Servlet,當別人訪問我這個Servlet的時候,它們就可以下載我這個圖片了
????????????(3)java的文件上傳下載都是通過io流來完成的,既然要下載圖片,首先要能夠讀取到它
????????????//獲取到資源的路徑
????????????String path =this.getServletContext().getRealPath("/download/1.png");
????????????//讀取資源
????????????FileInputStream fileInputStream =newFileInputStream(path);
????????????//獲取到文件名,路徑在電腦上保存是\\形式的。
????????????String fileName = path.substring(path.lastIndexOf("\\") +1);
? ??????????告訴瀏覽器,我要下載這個文件
????????????//設置消息頭,告訴瀏覽器,我要下載1.png這個圖片
????????????response.setHeader("Content-Disposition","attachment; filename="+fileName);
????????????將讀取到的內容回送給瀏覽器
????????????//把讀取到的資源寫給瀏覽器
????????????intlen?=0;
????????????byte[]?bytes?=newbyte[1024];
????????????ServletOutputStream?servletOutputStream?=?response.getOutputStream();
????????????while((len?=?fileInputStream.read(bytes))?>0)?{
????????????servletOutputStream.write(bytes,0,?len);
????????????}
????????????//關閉資源
????????????servletOutputStream.close();
????????????fileInputStream.close();
????????????(4)訪問瀏覽器就提示下載了。
????????????(5)解決文件名是中文時的亂碼問題:為了解決文件名亂碼,我們要進行URL編碼:
????????????response.setHeader("Content-Disposition", "attachment; filename=" + ????????????URLEncoder.encode(fileName, "UTF-8"));
????????4.5?實現自動刷新
????????????(1)response.setHeader("Refresh", "3"); ?// 3秒刷新一次
????????4.6?設置緩存
????????????(1)瀏覽器本身就存在著緩存機制,禁止緩存功能:
????????????//瀏覽器有三消息頭設置緩存,為了兼容性!將三個消息頭都設置了
????????????response.setDateHeader("Expires",?-1);
????????????response.setHeader("Cache-Control","no-cache");
????????????response.setHeader("Pragma","no-cache");
????????????//這里為了看效果
????????????PrintWriter?printWriter?=?response.getWriter();
????????????printWriter.print("你好啊"+newDate().toString());
????????4.7?重定向跳轉
????????????(1) response.sendRedirect("/zhongxiang/index.jsp");
? ??5.Servlet之 request? ??
? ??????(HttpServletRequest(客戶端的請求))
????????5.1?防盜鏈
????????????(獲取Referer消息頭,判斷是不是從我的首頁來的。不是則跳轉回首頁。)
????????????String referer = request.getHeader("Referer");//獲取到網頁是從哪里來的
????????????if ( referer == null || !referer.contains("localhost:8080/herewell/index.jsp") ) {
????????????? response.sendRedirect("/herewell/index.jsp");}
????????5.2?表單提交數據,獲取要提交的值
????????????request.setCharacterEncoding("UTF-8"); ?//設置request字符編碼的格式
????????????String username = request.getParameter("username");//輸入框和文本框一個值,獲取到一個值
????????????String[] hobbies = request.getParameterValues("hobbies");?//復選框下拉框有多個值,獲取到多個值
????????5.3 解決中文亂碼問題(Tomcat以ISO 8859-1編碼對中文編碼)
????????????1. request.setCharacterEncoding("UTF-8");//post 解決亂碼,因為post消息封裝到了request中
????????????2. get方法它的數據是從消息行帶過去的,沒有封裝到request對象里,使用request設置編碼無效。
????????????String name = request.getParameter("username");//此時是被ISO 8859-1編碼的字符串,亂碼
????????????byte[] bytes = name.getBytes("ISO8859-1");//亂碼通過反向查ISO 8859-1得到原始的數據
????????????String value = new String(bytes, "UTF-8");//通過原始的數據,設置正確的碼表,構建字符串
6.Cookie
????6.1 Cookie 定義:
給每一個用戶都發一個通行證,無論誰訪問的時候都需要攜帶通行證,這樣服務器就可以從通行證上確認用戶的信息。通行證就是Cookie
????6.2 ?Cookie的流程:
瀏覽器訪問服務器,如果服務器需要記錄該用戶的狀態,就使用response向瀏覽器發送一個Cookie,瀏覽器會把Cookie保存起來。當瀏覽器再次訪問服務器的時候,瀏覽器會把請求的網址連同Cookie一同交給服務器。
????6.3?Cookie API?
?Cookie類用于創建一個Cookie對象
?response接口中定義了一個addCookie方法,用于在其響應頭中增加一個相應的Set-Cookie頭字段
?request接口中定義了一個getCookies方法,用于獲取客戶端提交的Cookie
常用的Cookie方法:
- public Cookie(String name,String value)
- setValue與getValue方法
- setMaxAge與getMaxAge方法//設置Cookie的時間
- setPath與getPath方法
- setDomain與getDomain方法
- getName方法
????6.4?Cookie細節
????????1.Cookie不可跨域名性
Cookie具有不可跨域名性。瀏覽器判斷一個網站是否能操作另一個網站的Cookie的依據是域名。所以一般來說,當我訪問baidu的時候,瀏覽器只會把baidu頒發的Cookie帶過去,而不會帶上google的Cookie。
????????2.Cookie保存中文
2.1?Cookie使用Unicode字符時需要對Unicode字符進行編碼。
Cookie cookie = new Cookie("country", URLEncoder.encode(name, "UTF-8"));
2.2?在取出Cookie的時候要對中文數據進行解碼
Cookie[] cookies = request.getCookies();
? for (int i = 0; cookies != null && i < cookies.length; i++) {
? String name = cookies[i].getName();
? String value = URLDecoder.decode(cookies[i].getValue(), "UTF-8");
? printWriter.write(name + "------" + value);}
????????3.Cookie的有效期(setMaxAge()來設置)
3.1?如果MaxAge為正數,瀏覽器會把Cookie寫到硬盤中,只要還在MaxAge秒之前,登陸網站時該Cookie就有效
3.2?如果MaxAge為負數,**Cookie是臨時性的,僅在本瀏覽器內有效,關閉瀏覽器Cookie就失效了,Cookie不會寫到硬盤中。Cookie默認值就是-1。
3.3?如果MaxAge為0,則表示刪除該Cookie。
????????4.Cookie的修改和刪除
????????????????4.1 修改cookie ?
Cookie的名稱相同,通過response添加到瀏覽器中,會覆蓋原來的Cookie。
Cookie cookie = new Cookie("country", URLEncoder.encode(name, "UTF-8"));
????????????????4.2 刪除cookie ??
把MaxAge設置為0,并添加到瀏覽器中即可
cookie.setMaxAge(0);
response.addCookie(cookie)
注意:
刪除,修改Cookie時,新建的Cookie除了value、maxAge之外的所有屬性都要與原Cookie相同。否則瀏覽器將視為不同的Cookie,不予覆蓋,導致刪除修改失敗!
????????5.Cookie的域名(domain屬性決定運行訪問Cookie的域名)
cookie.setDomain(".herewell.com");
????????6.Cookie的路徑(path屬性決定允許訪問Cookie的路徑)
一般地,Cookie發布出來,整個網頁的資源都可以使用。現在我只想Servlet1可以獲取到Cookie,其他的資源不能獲取。
cookie.setPath("/Servlet1");
????????7.Cookie的安全屬性
設置Cookie的secure屬性為true,瀏覽器只會在HTTPS和SSL等安全協議中傳輸該Cookie。
7.Session
????7.1 Session定義:
Session保存在服務器中。用戶使用瀏覽器訪問服務器的時候,服務器把用戶的信息以某種的形式記錄在服務器,這就是Session
Session比Cookie使用方便,Session可以解決Cookie解決不了的事情【Session可以存儲對象,Cookie只能存儲字符串。】
????7.2 Session API
long getCreationTime();【獲取Session被創建時間】
String getId();【獲取Session的id】
long getLastAccessedTime();【返回Session最后活躍的時間】
ServletContext getServletContext();【獲取ServletContext對象】
void setMaxInactiveInterval(int var1);【設置Session超時時間】
int getMaxInactiveInterval();【獲取Session超時時間】
Object getAttribute(String var1);【獲取Session屬性】
Enumeration ??getAttributeNames();【獲取Session所有的屬性名】
void setAttribute(String var1, Object var2);【設置Session屬性】
void removeAttribute(String var1);【移除Session屬性】
void invalidate();【銷毀該Session】
boolean isNew();【該Session是否為新的】
????7.3 Session作為域對象(傳值)
只要Session對象沒有被銷毀,Servlet之間就可以通過Session對象實現通訊
? HttpSession httpSession = request.getSession(); ?//得到Session對象
? httpSession.setAttribute("name", "蔬菜!!");?//設置Session屬性
String value = (String) httpSession.getAttribute("name");//在其他servlet獲取傳遞的數據
????7.4 Session的生命周期和有效期
1.Session在用戶第一次訪問服務器Servlet,jsp等動態資源就會被自動創建,Session對象保存在內存里
2.無論是否對Session進行讀寫,服務器都會認為Session活躍了一次。(最后一次)
3.為防止內存溢出,服務器會把長時間沒活躍的Session從內存中刪除,這個就是Session的超時時間。
4.Session的超時時間默認是30分鐘,有三種方式可以對Session的超時時間進行修改
(1)在tomcat/conf/web.xml文件中設置,時間值為20分鐘,所有的WEB應用都有效
(2)在單個的web.xml文件中設置,對單個web應用有效,如果有沖突,以自己的web應用為準。
(3)通過setMaxInactiveInterval()方法設置
????7.5 ? Session的實現原理
HTTP協議是無狀態的,Session不能依據HTTP連接來判斷是否為同一個用戶。于是乎:服務器向用戶瀏覽器發送了一個名為JESSIONID的Cookie,它的值是Session的id值。其實Session依據Cookie來識別是否是同一個用戶。
簡單來說:Session之所以可以識別不同的用戶,依靠的就是Cookie
該Cookie是服務器自動頒發給瀏覽器的,不用我們手工創建的。該Cookie的maxAge值默認是-1,也就是說僅當前瀏覽器使用,不將該Cookie存在硬盤中
我理解的:每次連接服務器都會生成一個JESSIONID,他就是服務器自動頒發的cookie,cookie的默認maxAge是-1,過了cookie的時效期,就要重新連接服務器請求新的JESSIONID
????7.6 ? Session禁用Cookie
1.禁用自己項目的Cookie(META-INF文件夾下context.xml)
2.?禁用全部web應用的Cookie( 在conf/context.xml中修改)
????7.7 ? 利用Session防止表單重復提交
????????1.常見的重復提交
- 在處理表單的Servlet中刷新。
- 后退再提交
- 網絡延遲,多次點擊提交按鈕
????????2.session 處理
-判斷Session域對象的數據和jsp隱藏域提交的數據是否對應。
-判斷隱藏域的數據是否為空【如果為空,就是直接訪問表單處理頁面的Servlet】
-判斷Session的數據是否為空【servlet判斷完是否重復提交,最好能立馬移除Session的數據,如果Session域對象數據為空,證明已經提交過數據了!】
向Session域對象存入的數據是一個隨機數【Token--令牌】(生成的一個獨一無二的隨機數)。
實現原理:
在session域中存儲一個token
然后前臺頁面的隱藏域獲取得到這個token
在第一次訪問的時候,我們就判斷seesion有沒有值,如果有就比對。對比正確后我們就處理請求,接著就把session存儲的數據給刪除了
等到再次訪問的時候,我們session就沒有值了,就不受理前臺的請求了!
????7.8 ? Session和Cookie的區別
從存儲方式上比較
Cookie只能存儲字符串,如果要存儲非ASCII字符串還要對其編碼。
Session可以存儲任何類型的數據,可以把Session看成是一個容器
從隱私安全上比較
Cookie存儲在瀏覽器中,對客戶端是可見的。信息容易泄露出去。如果使用Cookie,最好將Cookie加密
Session存儲在服務器上,對客戶端是透明的。不存在敏感信息泄露問題。
從有效期上比較
Cookie保存在硬盤中,只需要設置maxAge屬性為比較大的正整數,即使關閉瀏覽器,Cookie還是存在的
Session的保存在服務器中,設置maxInactiveInterval屬性值來確定Session的有效期。并且Session依賴于名為JSESSIONID的Cookie,該Cookie默認的maxAge屬性為-1。如果關閉了瀏覽器,該Session雖然沒有從服務器中消亡,但也就失效了。
從對服務器的負擔比較
Session是保存在服務器的,每個用戶都會產生一個Session,如果是并發訪問的用戶非常多,是不能使用Session的,Session會消耗大量的內存。
Cookie是保存在客戶端的。不占用服務器的資源。像baidu、Sina這樣的大型網站,一般都是使用Cookie來進行會話跟蹤。
從瀏覽器的支持上比較
如果瀏覽器禁用了Cookie,那么Cookie是無用的了!
如果瀏覽器禁用了Cookie,Session可以通過URL地址重寫來進行會話跟蹤。
從跨域名上比較
Cookie可以設置domain屬性來實現跨域名
Session只在當前的域名內有效,不可夸域名
????7.9?Cookie和Session共同使用
1.創建Cookie,Cookie的值是Session的id返回給瀏覽器
2.在server.xml文件中配置,將每個用戶的Session在服務器關閉的時候序列化到硬盤或數據庫上保存(不常用)
參考資料:?Java3Y公眾號