# Servlet詳解
### 基本概述
????Session在計算機中,尤其是在網絡應用中,稱為“會話控制”。在計算機專業術語中,Session是指一個終端用戶與交互系統進行通信的時間間隔,通常指從注冊進入系統到注銷退出系統之間所經過的時間。具體到Web中的Session指的就是用戶在瀏覽某個網站時,從進入網站到關閉這個網站所經過的這段時間,也就是用戶瀏覽這個網站所花費的時間。因此從上述的定義中可以看到,Session實際上是一個特定的時間概念。
參考文檔:[http://tomcat.apache.org/tomcat-5.5-doc/servletapi/index.html](http://tomcat.apache.org/tomcat-5.5-doc/servletapi/index.html)
?
### Session工作原理圖

????Tomcat默認是30分鐘。
Tomcat主目錄的conf文件夾中的web.xml文件可以進行設置全局默認會話生命周期時間。

### 3種設置session生命周期的方法
#### 1、tomcat/conf/web.xml
????如上圖所示,將數字進行更改則行,單位為分鐘。
?
#### 2、在web應用下的web.xml
????直接在<web-app></web-app>中加入如圖所示代碼則行。
?
#### 3、通過request.getSession().setMaxInactiveInterval(time)
????time是以秒為單位的。time為正數表示用戶未操作多少秒后會話失效,0為立即失效,負數代表永不失效。
?
PS:session的生命周期的時間是指用戶未操作時間,也就是說當用戶未操作多少秒后失效。而cookie的生命周期的時間指得是累積的時間,也就說無論用戶訪問否,只要累積過去了多少秒后就失效了。
案例:
~~~
package com.pc;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URLDecoder;
import java.net.URLEncoder;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class Servlet12 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 字符編碼
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
response.setCharacterEncoding("utf-8");
PrintWriter out = response.getWriter();
// 訪問session [當發現沒用session時,就會自動創建session]
HttpSession session = request.getSession();
// 給該session放入屬性,可以加入對象
String val = URLEncoder.encode("張三", "utf-8");
session.setAttribute("name", val);
session.setAttribute("age", 20);
// session的生命周期(默認30min,可以修改)
// time指的是等待時間,如果超過這個時間,則會自動釋放該會話
// session.setMaxInactiveInterval(time);
out.println("創建session并放入屬性");
out.flush();
out.close();
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doGet(request, response);
}
}
~~~
~~~
package com.pc;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URLDecoder;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class Servlet13 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 字符編碼
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
response.setCharacterEncoding("utf-8");
PrintWriter out = response.getWriter();
// 獲取Session
HttpSession session = request.getSession();
// 獲取屬性
String name = (String) session.getAttribute("name");
Integer age = (Integer) session.getAttribute("age");
// 刪除name屬性
//session.removeAttribute("name");
if (name != null && age != null) {
out.println(URLDecoder.decode(name, "utf-8") + " " + age);
}
out.flush();
out.close();
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doGet(request, response);
}
}
~~~
### 小結
1、session存在于服務器的內存中
2、一個用戶瀏覽器,獨享一個session域對象
3、session中的屬性的默認生命周期是30min?,你可以通過?web.xml來修改
4、session中可以存放多個屬性
5、session?可以存放對象
6、如果?request.getSession().setAttribute(“name”,val)?,?如果名字重復,則會替換該屬性.
7、生命周期設置優先級順序為setMaxInactiveInterval?>?web應用下的web.xml設置?>?tomcat/conf/web.xml下的設置
8、1,2兩種方法之所以不能是秒級的一個關鍵原因是因為太耗費資源,3能是秒級的原因是因為它是對單個Session進行監控。
9、session生命周期時間指得是用戶未操作時間,當用戶訪問后,有從新計時,可以采取如下幾種方式使session或者其中屬性失效。
????1、重啟、reload應用、關機,session會完全失效。
????2、通過request.getSession().invalidate()讓session中所有屬性失效。
????3、通過request.getSession().removeAttribute()讓session中某一屬性失效、
### Session工作原理更深入的理解

PS:JSESSIONID是Session自動生成的用于唯一表示Session對象的一個ID號,通過該ID號服務器可以對每一個瀏覽器進行標識。
### JSESSION控制session銷毀時間
? ? 當關閉瀏覽器之后,因為session默認返回的Cookie是會話級別的,所以即使服務器那端session并沒有失效,再打開瀏覽器也無法使用之前的會話了。不過可以通過重設JSESSIONID這個Cookie來實現有效期持續到session生命周期完。
?
案例:
~~~
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
HttpSession session = request.getSession();
session.setAttribute("name", "張三");
out.println("創一個session并放入姓名屬性");
//把該session id保存cookie,在id時,一定要按照規范命名,這里區分大小寫
Cookie cookie = new Cookie("JSESSIONID", session.getId());
cookie.setMaxAge(60*30);
response.addCookie(cookie);
}
~~~
~~~
public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
HttpSession httpSession = request.getSession();
String name = (String) httpSession.getAttribute("name");
out.println("name = "+name);
}
~~~
### Cookie禁用后使用Session的方法
? ? cookie禁用后可以使用URL重寫的方法,來實現Session。
#### 基本語法:
response.encodeRedirectURL(java.lang.String?url)?
????用于對sendRedirect方法后的url地址進行重寫
response.encodeURL(java.lang.String?url)
????用于對表單action和超鏈接的url地址進行重寫
#### encodeURL?(String?url)方法的實現機制為:?
????先判斷當前的?Web?組件是否啟用?Session,如果沒有啟用?Session,直接返回參數?url,再判斷客戶端瀏覽器是否支持?Cookie,如果支持?Cookie,直接返回參數?url;如果不支持?Cookie,就在參數?url?中加入?Session?ID?信息,然后返回修改后的?url。
### cookie與session的比較
#### 1、存在的位置
????cookie:存在客戶端的臨時文件夾
????session:存在服務器內存中,一個session域對象為一個用戶瀏覽器服務
#### 2、安全性
????cookie:是以明文的方式放在客戶端的,安全性弱,可以通過(MD5)加密再存放。
????session:是存放在服務器內存中,所有安全性好
#### 3、網絡傳輸
????cookie:屬性值會傳遞信息給服務器?
????session:屬性值不會給客戶端
#### 4、生命周期
????cookie的生命周期:是累計時間,即如果我們給cookie設置setMaxAge(30),則30秒后失效。
????session的生命周期:是間隔時間,如我們設置session?20min,指在20min內,如果沒有訪問session,則session失效(session失效是指無法讀取session屬性),
在以下情況session也會失效
??(1)關閉tomcat??(2)reload??web應用??(3)時間到??(4)?調用invalidate方法
#### 5、作用范圍
????cookie:能夠被多個瀏覽器共享
????session:只能一個瀏覽器使用
#### 6、使用原則
????session:因為session會占用服務器的內存,因此不要向session中存放過多過大的對象,會影響性能。
????cookie:不要將太多數據放置在cookie中,這樣會使用大量帶寬。
?
?
?
----------參考《韓順平.細說Servlet》