JavaWeb開發基礎:Cookies學習
理解cookie的實現原理:
http協議的特性是無連接性,但我們從服務器上那下來網頁的內容之後,socket就close掉了,服務器和瀏覽器不再連接。
所以要使用cookie保存一些東西,比如用戶登錄狀態等一些客戶端和服務器端狀態的東西。
cookie是服務器保存在客戶端(瀏覽器)的鍵值對文本。
客戶端可以阻止服務器寫入cookie,在IE裏面設置就可以,但是很多分網站不能正常訪問。
cookie的種類:
有兩種cookie:
- 持久化的cookie,這種會保存在本地的cookie文件夾裏面,需要在代碼裏面設置生命週期(最大壽命MaxAge)
- 是session的cookie,只要瀏覽器窗口關閉(ctr+n創建子窗口除外),這種cookie就會消失。
生成cookie:
生成持久化cookie的代碼如下。
public class SetCookiesServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
for (int i = 0; i <3 ; i++) {
Cookie cookie = new Cookie("Session-Cookie-"+i,"Cookie-Value-S");
//設置cookie的生命週期爲1個小時
cookie.setMaxAge(3600);
resp.addCookie(cookie);
}
resp.setContentType("text/html;charset=gb2312");
PrintWriter out = resp.getWriter();
String title = "Setting Cookies";
out.println("<a href='showCookies'>yes!</a>");
}
}
上面代碼就生成了三個持久化的cookie,點擊url就可以訪問到展示cookies的頁面。
cookie.setMaxAge(3600);這行代碼的意思就是將cookie持久化,時間是3600秒,一個小時之後這個cookie就會被自動清理掉。
讀取cookie:
那麼展示cookie的代碼如下:
public class ShowCookiesServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=gb2312");
PrintWriter out = resp.getWriter();
String title = "Active cookies";
Cookie[] cookies = req.getCookies();
if(cookies!=null)
{
Cookie cookie;
for (int i = 0; i < cookies.length; i++) {
cookie = cookies[i];
out.println("<tr>\n"+"<td>"+cookie.getName()+"</td>\n"
+"<td>"+cookie.getValue()+"</td><tr>\n");
}
}
}
}
這樣,就把上面設置的三個cookie展示了出來,這樣做的目的無非就是說明,使用response去獲得cookie,使用request去獲取cookie。
注意!設置cookie的頁面,必須和獲取cookie的頁面是在同一個url路徑,或者設置cookie的頁面的url路徑必須包含獲取cookie的頁面,比如我設置cookie的路徑是.../setCookie,那麼我的獲取cookie的頁面url可以是..../hello/getCookie,但是不能是設置路徑爲.../helllo/setCookie,而獲取路徑爲..../getCookie。
結論:父親寫,兒子,叔叔能讀,但是爺爺不能讀。
Session篇章:
概要:
和cookie不同的是,session是記錄在服務器端的。
理解session的實現原理:
服務器端可以爲某個客戶端開闢一個內存,這個內存可以和一個客戶端的窗口和子窗口關聯在一起。每個瀏覽器和服務器端的關聯內容可以保證一一對應,而不會訪問其他人的session。原理就是每次瀏覽器訪問服務端的時候都會有一個獨一無二的號碼,session也會對應擁有這個號碼。當第二個頁面訪問服務器的時候,會再次按照這個號碼查找內存中的session。這個號碼就是sessionid
session的兩種實現方式:
- cookie實現:每個客戶端在訪問session的時候,必須傳遞sessionid,那麼這個sessionid可以保存在cookie裏面。開啓cookie之後,session的實現就可以依賴cookie
- url重寫實現:cookie不允許,必須自己編程使用url重寫的方式來實現session。利用的是response.encodeURL這個方法
cookie實現session代碼:
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
/**
* 用於演示Servlet API中的Session管理機制
*/
public class SessionInfoServlet extends HttpServlet {
/**
* Builds an HTML document containing session information and returns it to
* the client.
*/
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// get current session or, if necessary, create a new one
HttpSession mySession = request.getSession(true);
// MIME type to return is HTML
response.setContentType("text/html");
// get a handle to the output stream
PrintWriter out = response.getWriter();
// generate HTML document
out.println("<HTML>");
out.println("<HEAD>");
out.println("<TITLE>Session Info Servlet</TITLE>");
out.println("</HEAD>");
out.println("<BODY>");
out.println("<H3>Session Information</H3>");
out.println("New Session: " + mySession.isNew());
out.println("<BR>Session ID: " + mySession.getId());
out.println("<BR>Session Creation Time: "
+ new java.util.Date(mySession.getCreationTime()));
out.println("<BR>Session Last Accessed Time: "
+ new java.util.Date(mySession.getLastAccessedTime()));
out.println("<H3>Request Information</H3>");
out.println("Session ID from Request: "
+ request.getRequestedSessionId());
out.println("<BR>Session ID via Cookie: "
+ request.isRequestedSessionIdFromCookie());
out.println("<BR>Session ID via rewritten URL: "
+ request.isRequestedSessionIdFromURL());
out.println("<BR>Valid Session ID: "
+ request.isRequestedSessionIdValid());
out.println("</BODY></HTML>");
out.close(); // close output stream
}
/**
* Returns a brief description of this servlet.
*
* @return Brief description of servlet
*/
@Override
public String getServletInfo() {
return "Servlet returns session information.";
}
}
部署好之後,訪問這個url的效果如下。
這個時候我們可以在cookie文件中保存着上面相同sessionid的一個記錄
說明在創建這個session的時候,cookie裏面一條記錄已經保存了這個sessiondi
要點:
- 如果瀏覽器支持cooike,創建session的時候會把id保存在cookie裏面。
- 如果瀏覽器被用戶設置阻止訪問cookie,那麼每一次刷新當前窗口都會變化一個sessionid。每次生成的session都不一樣,那麼這樣的sessionid就沒有意義,因爲訪問不了內存內容(老版本的ie可能存在不能禁用cookie的問題)。
URL重寫實現session代碼:
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
/**
* 用於演示Servlet API中的Session管理機制
*/
public class SessionInfoServlet extends HttpServlet {
/**
* Builds an HTML document containing session information and returns it to
* the client.
*/
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// get current session or, if necessary, create a new one
HttpSession mySession = request.getSession(true);
// MIME type to return is HTML
response.setContentType("text/html");
// get a handle to the output stream
PrintWriter out = response.getWriter();
// generate HTML document
out.println("<HTML>");
out.println("<HEAD>");
out.println("<TITLE>Session Info Servlet</TITLE>");
out.println("</HEAD>");
out.println("<BODY>");
out.println("<H3>Session Information</H3>");
out.println("New Session: " + mySession.isNew());
out.println("<BR>Session ID: " + mySession.getId());
out.println("<BR>Session Creation Time: "
+ new java.util.Date(mySession.getCreationTime()));
out.println("<BR>Session Last Accessed Time: "
+ new java.util.Date(mySession.getLastAccessedTime()));
out.println("<H3>Request Information</H3>");
out.println("Session ID from Request: "
+ request.getRequestedSessionId());
out.println("<BR>Session ID via Cookie: "
+ request.isRequestedSessionIdFromCookie());
out.println("<BR>Session ID via rewritten URL: "
+ request.isRequestedSessionIdFromURL());
out.println("<BR>Valid Session ID: "
+ request.isRequestedSessionIdValid());
//和上面代碼不同的是這一行
out.println("<br><a href="+"SessionInfoServlet"+">refresh</a>");
out.println("</BODY></HTML>");
out.close(); // close output stream
}
/**
* Returns a brief description of this servlet.
*
* @return Brief description of servlet
*/
@Override
public String getServletInfo() {
return "Servlet returns session information.";
}
}