Cookie
Cookie机制
在程序中,会话跟踪是很重要的事情。理论上,一个用户的所有请求操作都应该属于同一个会话,而另一个用户的所有请求操作则应该属于另一个会话,二者不能混淆。例如,用户A在超市购买的任何商品都应该放在A的购物车内,不论是用户A什么时间购买的,这都是属于同一个会话的,不能放入用户B或用户C的购物车内,这不属于同一个会话。
而Web应用程序是使用HTTP协议传输数据的。HTTP协议是无状态的协议。一旦数据交换完毕,客户端与服务器端的连接就会关闭,再次交换数据需要建立新的连接。这就意味着服务器无法从连接上跟踪会话。即用户A购买了一件商品放入购物车内,当再次购买商品时服务器已经无法判断该购买行为是属于用户A的会话还是用户B的会话了。要跟踪该会话,必须引入一种机制。
Cookie就是这样的一种机制。它可以弥补HTTP协议无状态的不足。在Session出现之前,基本上所有的网站都采用Cookie来跟踪会话。
什么是Cookie
Cookie意为“甜饼”,是由W3C组织提出,最早由Netscape社区发展的一种机制。目前Cookie已经成为标准,所有的主流浏览器如IE、Netscape、Firefox、Opera等都支持Cookie。
由于HTTP是一种无状态的协议,服务器单从网络连接上无从知道客户身份。怎么办呢?就给客户端们颁发一个通行证吧,每人一个,无论谁访问都必须携带自己通行证。这样服务器就能从通行证上确认客户身份了。这就是Cookie的工作原理。
Cookie实际上是一小段的文本信息。客户端请求服务器,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个Cookie。客户端浏览器会把Cookie保存起来。当浏览器再请求该网站时,浏览器把请求的网址连同该Cookie一同提交给服务器。服务器检查该Cookie,以此来辨认用户状态。服务器还可以根据需要修改Cookie的内容。
从请求中拿到 cookie 信息
服务器响应给客户端 cookie
Cookie[] cookies = req.getCookies(); //获得Cookie
cookie.getName(); //获得cookie中的key
cookie.getValue(); //获得cookie中的vlaue
new Cookie("lastLoginTime", System.currentTimeMillis()+""); //新建一个cookie
cookie.setMaxAge(24*60*60); //设置cookie的有效期
resp.addCookie(cookie); //响应给客户端一个cookie
cookie : 一般会保存在本地的用户目录下 appdata ;
- 一个 Web 站点可以给浏览器发送多个 Cookie,最多存放 20 个 cookie;
- cookie 大小有限制 4kb;
- 300 个 cookie 浏览器上限
删除 Cookie; - 不设置有效期,关闭浏览器,自动失效;
- 设置有效期为 0;
编码解码:
URLEncoder.encode("秦疆","utf-8")
URLDecoder.decode(cookie.getValue(),"UTF-8")
参考代码
package com.maven.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
import static java.lang.System.out;
public class TestCookie extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//服务器,告诉你,你来的时间,把这个时间封装成一个信件,你来了我就知道你来了
//解决中文乱码
req.setCharacterEncoding("utf-8");
//resp.setHeader("context-type","text/html;charset=UTF-8");
resp.setContentType("text/html");
resp.setCharacterEncoding("utf-8");
PrintWriter writer = resp.getWriter();
// Cookie,服务器端从客户端获取
Cookie[] cookies = req.getCookies();
//判断Cookie是否存在
if (cookies!=null){
//如果存在怎么办
writer.write("你上一次访问的时间是:");
for (Cookie cookie:cookies){
//获取Cookie名字
if (cookie.getName().equals("lastLoginTime")){
//获取cookie中的值
long lastLoginTime = Long.parseLong(cookie.getValue());
Date date = new Date(lastLoginTime);
writer.write(date.toLocaleString());
}
}
}else {
writer.write("这是你第一次访问本网站");
}
//服务器给客户端响应一个cookie
Cookie cookie = new Cookie("lastLoginTime", System.currentTimeMillis() + "");
//cookie的有效期为1天
cookie.setMaxAge(24*60*60);
//cookie的有效期为0,立马过期
// cookie.setMaxAge(0);
resp.addCookie(cookie);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
Session
什么是session
使用Cookie和附加URL参数都可以将上一次请求的状态信息传递到下一次请求中,但是如果传递的状态信息较多,将极大降低网络传输效率和增大服务器端程序处理的难度。
Session技术是一种将会话状态保存在服务器端的技术 ,它可以比喻成是医院发放给病人的病历卡和医院为每个病人保留的病历档案的结合方式 。
客户端需要接收、记忆和回送 Session的会话标识号,Session可以且通常是借助Cookie来传递会话标识号。
同一用户的不同页面共享数据(Session)
使用session
Session的跟踪机制
1.Servlet API规范中定义了一个HttpSession接口,HttpSession接口定义了各种管理和操作会话状态的方法。
2.HttpSession对象是保持会话状态信息的存储结构,一个客户端在WEB服务器端对应一个各自的HttpSession对象。
3.WEB服务器并不会在客户端开始访问它时就创建HttpSession对象,只有客户端访问某个能与客户端开启会话的Servlet程序时,WEB应用程序才会创建一个与该客户端对应的HttpSession对象。
4.WEB服务器为HttpSession对象分配一个独一无二的会话标识号,然后在响应消息中将这个会话标识号传递给客户端。客户端需要记住会话标识号,并在后续的每次访问请求中都把这个会话标识号传送给WEB服务器,WEB服务器端程序依据回传的会话标识号就知道这次请求是哪个客户端发出的,从而选择与之对应的HttpSession对象
使用session
package com.maven.session;
import javax.servlet.ServletException;
import javax.servlet.http.*;
import java.io.IOException;
public class TestSession extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//解决乱码问题
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
resp.setContentType("text/html;charset=utf-8");
//得到Session
HttpSession session = req.getSession();
//给Session中存东西
session.setAttribute("name", new Person("秦疆", 1));
//获取Session的ID
String sessionId = session.getId();
//判断Session是不是新创建
if (session.isNew()) {
resp.getWriter().write("session创建成功,ID:" + sessionId);
} else {
resp.getWriter().write("session以及在服务器中存在了,ID:" + sessionId);
}
//Session创建的时候做了什么事情;
// Cookie cookie = new Cookie("JSESSIONID",sessionId);
// resp.addCookie(cookie);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
// //得到Session
// HttpSession session = req.getSession();
//
// Person person = (Person) session.getAttribute("name");
//
//System.out.println(person.toString());
//
// HttpSession session=req.getSession();
// session.removeAttribute("name");
//手动注销Session
// session.invalidate();
person类
package com.maven.session;
public class Person {
private String name;
private int age;
public Person() {
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
会话自动过期
<!--设置Session默认的失效时间-->
<session-config>
<!--15分钟后Session自动失效,以分钟为单位-->
<session-timeout>15</session-timeout>
</session-config>