1、會話:什麼叫會話?由同一個客戶端,向同一個服務器系統發起的1---N次請求。
2、會話跟蹤:見名知義,用來跟蹤用戶的整個會話;由於HTTP協議天生是無狀態的,客戶端提交數據完畢後,就會失去服務器與客戶端的連接,當再次請求時,需要建立新的連接,因此無法再連接上建立會話跟蹤。 另外,在基於http協議與服務器交互過程中,服務器無法主動記錄用戶的狀態信息,進而也無法跟蹤用戶與服務器的會話;爲了解決這一問題,cookie和session相關技術相繼誕生。
cookie技術:服務器根據客戶端保存的信息,確定用戶的身份。
session技術:服務器根據服務器保存的信息,確定用戶的身份。
3、Cookie技術(cookie類位於javax.servlet.http.*)
3.1)cookie是由服務器頒發給客戶端的一小段文本信息,這段文本信息存儲在客戶端的瀏覽器上。
3.2)Cookie原理:(Cookie的原理相當於一個人的身份證)
當客戶第一次發送請求的時候,服務器會給頒發給客戶端一個標記(信息存放在響應頭上,返回客戶端並記錄在瀏覽器上),當客戶端再次向該服務發起請求時(請求頭攜帶信息),會把標記發給服務器,此時服務器就能根據請求頭分析用戶特有的信息,從而動態生成客戶特有的網站信息。(應用實例:比如記住密碼)
3.3)(瞭解)cookie存在有兩種方式:如果說cookie生存時間是一個會話期間,那麼瀏覽器將會把cookie保存在一個內存中,關閉瀏覽器時, 此cookie被銷燬。另一種方式,將cookie存放在硬盤上,關閉瀏覽器,也不會被銷燬,當客戶端再次訪問同一個網站的時候,瀏覽器就會尋找響應的cookie,並將此信息發送到服務器端。
3.4)如果查看一個網站的cookie的話,只需在地址欄上輸入javascript:alter(document. cookie);但是一般都會被做加密處理。
3.5)cookie是有客戶端瀏覽器自動管理,所有cookie具有不可跨域性(有cookie的隱性安全機制決定)(瀏覽器做特殊處理外).
3.6) cookie的使用:
創建一個Cookie: Cookie cookie = new Cookie(Stirng name,Object value);
設置Cookie到客戶端瀏覽器:response.addCookie(cookie);
獲取客戶端瀏覽的cookie:Cookie cookies[] = request,getCookies( );
其餘常用方法:getName(),getValue(),setPath(url),setMaxAge( )
3.7) cookie的生命週期:默認情況下,cookie的存活時間是與瀏覽器綁定。關閉瀏覽器銷燬。
但是可以通過手動設置cookie的存活時間 :cookie.setMaxAge(10000)單位是秒,可以使0和負數
0是刪除當前cookie,負數時與當前瀏覽器進行綁定。(默認是-1)
3.8)cookie的缺陷:1)cookie以明文存儲信息,數據不安全
2)cookie存儲的信息量小,默認是4KB
3)cookie默認不支持中文。
4)cookie可以被禁用
注意:cookie功能需要瀏覽器的支持。
4、session技術
4.1)session技術也可以解決會話跟蹤技術,較cookie較簡單,session信息會存在服務器內,相對增加了服務器的存儲壓力。因此,出現了session的持久化技術。
4.2)session原理:
當用戶第一次請求服務器創建session的時候,服務器會在創建好的session同時,將當前session的id,主動設置到客戶端瀏覽器的cookie上保存,這個cookie是:jsessionid = sessionid(,,,,,,,,,,,,,,,,,,,,,,,,),下次請求到達服務器時,服務器主動獲取客戶端瀏覽器的jsessionid,進而可以找到對應的session對象。
session實現原理基於cookie(外來博客)
4.3)session的使用:
HttpSession session = request.getSession(true); //獲取session
session.setAttribute(String name,Object value); //存值
Object value = session.getAttribute(String name); //取值
session.removeAttribute(String name); //移除一個屬性
4.4)session的生命週期:
begin: 第一次調用request.getSession(true);
end: 手動銷燬session.invalidate()
超時策略:服務器默認銷燬(一般是20-30分鐘),配置web.xml
<session-config>
<session-timeout>30</session-timeout> <!--單位分鐘-->
</session-config>
可以通過setMaxInactiveInterval(Long interval) 設置超時時間(單位秒);
注意:超時時間 指 從用戶最後一次請求結束開始計算。
4.5)由於session依賴於cookie,如果瀏覽器將cookie禁掉,session就不能使用了,那麼該怎麼解決這一問題?
利用URL重寫:url地址重寫是對客戶端不支持cookie的解決方案。其原理是將session的id重新寫到url地址中,服務器能夠解析重寫後的URL獲取session的id;HttpServletResponse類提供了encodeURL(String url)實現url重寫。該方法自動判斷客戶端是否支持cookie,如果客戶端不支持cookie,會將用戶session的id重寫到URL中,如果支持,則不重寫。重寫後的URL會變爲”;jsessionid=XXXXXXX“
4.6)session應用場景:強制登陸、安全退出、購物車、用戶驗證碼
5、Cookie機制與Session機制的主要區別:
Cookie是採用客戶端保持狀態方案,而Session是採用服務器保持狀態方案。
https://blog.csdn.net/u011145904/article/details/77745777(含義更詳細的區別)
6、Cookie實現簡單登陸
login.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>login</title>
</head>
<body>
<%!
String username = "";
String password="";
String currentTime="";
%>
<%
Cookie[] cookies = request.getCookies();
//判斷cookies是否爲空
if(cookies!=null){
//不爲空,則遍歷cookie
for (Cookie cookie : cookies) {
if("username".equals(cookie.getName())){
username = cookie.getValue();
}
if("password".equals(cookie.getName())){
password = cookie.getValue();
}
if("currentTime".equals(cookie.getName())){
currentTime = cookie.getValue();
}
}
}
%>
<p>username :<%=username %><br/>
password:<%=password %><br/>
您當前登陸的時間:<%=currentTime %>
</p>
<form action="/bz1/login1" method="post">
用戶名:<input type="text" name="username" value=<%=username %> ><br/>
密碼:<input type="text" name="password"value=<%=password %> ><br/>
<input type="submit" value="提交">
</form>
</body>
</html>
loginServlet.java
@WebServlet("/login1")
public class TestSessionServlet extends HttpServlet{
public void service(HttpServletRequest request,HttpServletResponse response) throws IOException{
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
response.setContentType("text/html");
String username = request.getParameter("username");
String password = request.getParameter("password");
//獲取當前的時間
String currentTime = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date());
//創建cookie
Cookie cookie1 = new Cookie("username",username);
Cookie cookie2 = new Cookie("password",password);
Cookie cookie3 = new Cookie("currentTime",currentTime);
//設置存活時間
cookie1.setMaxAge(60*60*24*7);
cookie2.setMaxAge(60*60*24*7);
cookie3.setMaxAge(60*60*24*7);
//將cookie設置到瀏覽器上
response.addCookie(cookie1);
response.addCookie(cookie2);
response.addCookie(cookie3);
response.sendRedirect(request.getContextPath()+"/login.jsp");
}
}
運行截圖:
7、session實現登陸和註銷小案例:
login.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>login</title>
</head>
<body>
<form action="/bz1/login3" method="post">
用戶名:<input type="text" name="username" value=<%=username %> ><br/>
密碼:<input type="text" name="password"value=<%=password %> >
<input type="submit" value="提交">
</form>
</body>
</html>
success.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<body>
<h1>歡迎您!${user.username }</h1>
<a href="/bz1/outSalf">安全退出</a>
</body>
</html>
SessionLogin.java
package SessionServlet;
import java.io.IOException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import entity.Person;
@WebServlet("/login3")
public class SessionLogin extends HttpServlet{
public void service(HttpServletRequest request,HttpServletResponse response) throws IOException{
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
response.setContentType("text/html");
//假如我有一個數據裏,裏面有一條數據:username = 'sqc' 密碼='123456'
Person p = new Person("sqc","123456");
//接收頁面傳過來的username 和 password
String username = request.getParameter("username");
String password = request.getParameter("password");
if(p.getUsername().equals(username) && p.getPassword().equals(password)){
/**
* request.getSession()與request.getSession(true) 如果session不存在,創建一個session
* request.getSession(false) 如果session不存在,不創建
*/
//創建一個session對象
HttpSession session = request.getSession(true);
//登陸成功後,向session中存入session對象
session.setAttribute("user", p);
response.sendRedirect(request.getContextPath()+"/success.jsp");
return ;
} else{
response.getWriter().println("用戶名或密碼錯誤!");
}
}
}
OutSalfServlet.java
package SessionServlet;
import java.io.IOException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
@WebServlet("/outSalf")
public class OutSalfServlet extends HttpServlet{
public void service(HttpServletRequest request,HttpServletResponse response) throws IOException{
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
response.setContentType("text/html");
HttpSession session = request.getSession();
if(session==null){
response.sendRedirect(request.getContextPath()+"/login.jsp");
return ;
}
session.removeAttribute("user");
response.sendRedirect(request.getContextPath()+"/login.jsp");
}
}
運行截圖:
8、判斷session是否已經在服務器中創建
jsp頁面代碼是個登陸代碼,已經省略。
package SessionServlet;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import entity.Person;
@WebServlet("/login2")
public class TestSession extends HttpServlet{
public void service(HttpServletRequest request,HttpServletResponse response) throws IOException{
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
response.setContentType("text/html");
String username = request.getParameter("username");
String password = request.getParameter("password");
//將數據封裝成一個對象
Person p = new Person(username,password);
//創建一個session
HttpSession session = request.getSession(true);
//將數據存儲到session中
session.setAttribute("person", p);
//獲取session的id
String sessionId = session.getId();
if(session.isNew()){
response.getWriter().print("session創建成功!");
}else{
response.getWriter().print("服務器已存在該session,session的id:"+sessionId);
}
}
}