一、Cookie
Cookie数据是由客户端来保存和携带的,所以称之为客户端技术。
创建一个cookie,cookie是servlet发送到 Web 浏览器的少量信息。这些信息由浏览器保存,然后发送回服务器cookie 的值可以唯一地标识客户端,因此 cookie 常用于会话管理。
一个cookie拥有一个名称、一个值和一些可选属性,比如注释、路径和域限定符、最大生存时间和版本号。一些Web浏览器在处理可选属性方面存在bug,因此有节制地使用这些属性可提高 serviet 的互操作性。
servlet 通过使用 HttpServletResponse#addCookie 方法将 cookie发送到浏览器:该方法将字段添加到 HTTP响应头以便一次一个地将 cookie 发送到浏览器。浏览器应该支持每台Web服务器有20个cookie,总共有300个cookie,并且可能将每个cookie的大小限定为4 KB。
浏览器通过向HTTP请求头添加字段将cookie返回给serlet可使用HttpServletRequest#getCookies 方法从请求中获取cookie。一些 cookie可能有相同的名称,但却有不同的路径属性。
cookie影响使用它们的Web页面的缓存。HTTP 1.0不会缓存那些使用通过此类创建的cookie的页面。此类不支持HTTP 1.1中定义的缓存控件。
此类支持版本0(遵守Netscape协议)和版本1(遵守RFC 2109协议) cookie规范。默认情况下, cookie是使用版本0创建的,以确保最佳互操作性。
cookie容量:一个浏览器最多保存300个cookie。每个站点做多保存20个cookie,每个cookie的大小限制是4kb。
cookie默认存活时间:浏览器关闭的时候结束。
cookie持久化:若希望浏览器将cookie存储到磁盘上就需要用到maxAge(),以秒为单位的时间。
cookie删除:删除cookie时,path必须一致,否则不会被删除。
属性:
1、name:名称不能唯一确定一个Cookie。路径可能不同。
2、value:不能存中文。
3、path:默认值是写Cookie的那个程序的访问路径。
比如:http://localhost:8080/day10_00_cookie/servlet/login写的Cookie path就是:/day10_00_cookie看当前创建cookie的资源(servlet)文件路径 也可以是reuest.getContextPath();获取当前应用的路径。
客户端在访问服务器另外资源时,根据访问的路径来决定是否带着Cookie到服务器。
当前访问的路径如果是以cookie的path开头的路径,浏览器就带。否则不带。
4、maxAge(有效存活时间):cookie的缓存时间。默认是-1(默认存在浏览器的内存中)。单位是秒。
负数:cookie的数据存在浏览器缓存中。
0:删除。路径要保持一致,否则可能删错人。
正数:缓存(持久化到磁盘上)的时间。
cookie在磁盘上持久化的文本形式:
cookie在磁盘上持久化的文本形式:
public class CookieDemo1 extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=UTF-8");
PrintWriter pw = resp.getWriter();
Cookie[] cookies = req.getCookies();
for (int i = 0;cookies!=null&& i < cookies.length; i++) {
if("lastAccessTime".equals(cookies[i].getName())) {
long l = Long.parseLong(cookies[i].getValue());
pw.write("您上次的登陆时间为:"+new Date(l).toLocaleString());
}
}
//删除cookie跳转的servlet
pw.print("<a href='"+req.getContextPath()+"/servlet/clear'>clear cookie</a>");
//创建cookie
Cookie ck = new Cookie("lastAccessTime", System.currentTimeMillis()+"");
//设置cookie的有效时间,单位是秒
// ck.setMaxAge(5*60);
//设置cookie的path
// ck.setPath("/day10_00_cookie/servlet");
// ck.setPath(req.getContextPath()); //建议这两种写法 表示当前的应用/day10_00_cookie
ck.setPath("/"); //表示 /day10_00_cookie ck.setPath("http://www.taobao.com");==>也可以将cookie带到该网站
resp.addCookie(ck); //需要将cookie添加给响应报文==>设置好了cookie的相关属性再进行添加
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req, resp);
}
}
cookie的取出:
public class CookieDemo2 extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=UTF-8");
PrintWriter pw = resp.getWriter();
Cookie[] cookies = req.getCookies();
for (int i = 0;cookies!=null&& i < cookies.length; i++) {
if("lastAccessTime".equals(cookies[i].getName())) {
long l = Long.parseLong(cookies[i].getValue());
pw.write("您上次的登陆时间为:"+new Date(l).toLocaleString());
}
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req, resp);
}
}
cookie的清除
public class ClearServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//创建一个cookie对象
Cookie ck = new Cookie("lastAccessTime", "");
//和创建cookie时候的路径path对应起来,不然可能会删除对象
ck.setPath("/");
ck.setMaxAge(0);
resp.addCookie(ck);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
二、Session
Session:在计算机中,尤其是在网络应用中,称为“会话控制”。Session对象存储特定用户会话所需的属性及配置信息。这样,当用户在应用程序的 Web 页之间跳转时,存储在 Session 对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。当用户请求来自应用程序的 Web 页时,如果该用户还没有会话,则 Web 服务器将自动创建一个Session 对象。当会话过期或被放弃后,服务器将终止该会话。Session对象最常见的一个用法就是存储用户的首选项。例如,如果用户指明不喜欢查看图形,就可以将该信息存储在Session对象中。有关使用Session对象的详细信息,请参阅"ASP应用程序"部分的"管理会话”。注意 会话状态仅在支持 cookie 的浏览器中保留。
也是一个域对象: session(多servlet可以共享一个session数据) servletContext(整个应用的范围) request(servlet执行之前创建,结束的时候销毁。)
session默认存活时间:30min。
同一个会话下,可以使一个应用的多个资源共享数据。
cookie客户端技术,只能存字符串。HttpSession服务器端的技术,可存储对象。
在WEB开发中,服务器为每一个客户端(请求你创建且没有session才创建)创建一个会话对象(session对象)。注意一个浏览器独占一个session对象.
原理详解:
session机制是一种服务器端的机制。
用来在无状态的HTTp协议下越过多个请求页面来维持和识别用户。
当程序需要为某个客户端的请求创建一个session的时候,
服务器首先检查这个客户端的请求里是是否包含一个session id标识。
如果包含一个session id则说明以前为此客户端创建过session。
服务器就按照session id把这个session检索出来使用,若没有创建过,则创建一个新的Session。
创建时机:
HttpSession session = request.getSession();
如果当前没有session,则会立刻建立一个session;
如果有session则返回当前session。
这句话和HttpSession session = request.getSession(true);的效果是一样的。
HttpSession session = request.getSession(false);
则不会自动建立session。
若当前没有session,你所得到的seesion只会是一个null。
总结:
session不是一打开网站就会立刻建立。
它的建立需要基于下面两个条件中的任意一个:
1、在servlet中手动调用
HttpSession session = request.getSession();
或者
HttpSession session = request.getSession(true);
2、jsp中没有写<%@ page session="false"%>
(默认情况下它是<%@ page session="true"%>的)
如果两个条件同时都不满足,那么你建立的只是一个无seesion的连接。
session格式:
30min后服务端的session和客户端的JSESSIONID=xxx,才会被删除掉。重新调用HttpSession session = request.getSession();
重新创建此两个对象。
常用方法:
把数据保存在HttpSession对象中,该对象也是一个域对象。
void setAttribute(String name,Object value);
Object getAttribute(String name);
void removeAttribute(String name);
HttpSession.getId():
setMaxInactiveInterval(int interval) 设置session的存活时间 单位s
或者使用配置文件的方式
<session-config>
<!-- 设置session的有效时间,单位是分钟 -->
<session-timeout>10</session-timeout>
</session-config>
invalidate() 使此会话无效。
getSession():内部执行原理
1、获取名称为JSESSIONID的cookie的值。
2、没有这样的cookie,服务端创建一个新的HttpSession对象,分配一个唯一的SessionID。并且在浏览器中写一个名字为JSESSIONID=sessionID(dbe22defb...)的cookie。
3、有这样的Cookie,获取cookie的值(dbe22defb...),从服务器的内存中找到对应的HttpSession对象。
HttpSession request.getSession(boolean create):
true:和getSession()功能一样。
false:根据客户端JSESSIONID的cookie的值,找对应的HttpSession对象,找不到返回null(不会创建新的,只是查询)。
客户端禁用cookie后的会话数据保存问题:
客户端禁用cookie:浏览器永远不会向服务器发送cookie的请求消息头。
或者存在浏览器不支持cookie技术。==>看浏览器有没有发送cookie请求消息头,没有就重写URL,有就不重写。
解决方案:
方案一:在主页上给出提示:请不要禁用您的cookie。
方案二:URL重写。必须对网站的所有地址都重写。
public String encodeURL(String url)
通过将会话ID 包含在指定 URL 中对该 URL进行编码,如果不需要编码,则返回未更改的URL。此方法的实现包含可以确定会话 ID 是否需要在 URL 中编码的逻辑。例如,如果浏览器支持 cookie,或者关闭了会话跟踪,则 URL 编码就不是必需的。
对于健壮的会话跟踪,servlet 发出的所有 URL 都应该通过此方法运行。否则,URL 重写不能用于不支持 cookie 的浏览器。
url 要编码的 URL。
return 如果需要编码,则返回编码的 URL;否则返回未更改的 URL。
示例:
public class AddCart extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=UTF-8");
PrintWriter out =resp.getWriter();
String id = req.getParameter("id");
Book book = DBUtil.getBookById(id);
HttpSession session = req.getSession(); //这时候是带JSESSIONID来找session
ArrayList<Book> list = (ArrayList<Book>) session.getAttribute("cart");
if(null==list) {
list =new ArrayList<Book>();
}
list.add(book);
session.setAttribute("cart", list);
out.write("购买成功:"+book.getName());
String url = req.getContextPath()+"/servlet/showAll";
resp.setHeader("refresh", "2;url="+resp.encodeURL(url));
// resp.setHeader("refresh", "2;url="+req.getContextPath()+"/servlet/showAll");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
评论