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.";
}
}