目录
cookie:客户端会话技术
原理
常用API
注意问题
cookie的特点和作用
Session:服务器端会话技术
原理
常用API
注意
session的特点
概念
一次会话中包含多次请求和响应。 一次会话浏览器第一次给服务器资源发送请求,会话建立,直到有一方断开为止。在一次会话的多次请求间,共享数据
cookie:客户端会话技术
原理
客户端第一次向服务器发出请求,服务器给出响应(包含响应头set-cookie=a)
客户端向服务器发出请求(此时包含请求头cookie=a)
常用API
- cookie cookie(String name, String value) 创建cookie对象
- response.addcookie(cookie cookie) 发送cookie对象
- cookie[] request.getcookies() 获取cookie,拿到数据
- setMaxAge(int seconds) 持久化存储
- 正数将cookie数据写到硬盘的文件中。持久化存储。并指定cookie存活时间,时间到后,cookie文件自动失效
- 负数默认值
- 零删除cookie信息
示例代码
//cookie1:添加cookie
protected void doPost(HttpServletRequest request, HttpServletResponse response) thros ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
cookie cookie = ne cookie("name", "tom");//建立cookie对象
response.addcookie(cookie);//添加cookie
}
//cookie2:获取cookie
protected void doPost(HttpServletRequest request, HttpServletResponse response) thros ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
cookie[] cookies = request.getcookies();//获取cookie的信息
for (cookie cookie : cookies) {
System.out.println(cookie.getName()+":"+cookie.getValue());
}
}
注意问题
一次可以发送多个cookie,可以创建多个cookie对象,使用response调用多次addcookie方法发送cookie即可
cookie在浏览器中保存多长时间?
- 默认情况下,当浏览器关闭后,cookie数据被销毁
- 持久化存储setMaxAge(int seconds)
cookie共享问题
假设在一个tomcat服务器中,部署了多个eb项目,那么在这些eb项目中cookie能不能共享?
- 默认情况下cookie不能共享
- setPath(String path):设置cookie的获取范围。默认情况下,设置当前的虚拟目录
不同的tomcat服务器间cookie共享问题?
setDomain(String path):如果设置一级域名相同,那么多个服务器之间cookie可以共享
- setDomain(".baidu."),那么tieba.baidu.和nes.baidu.中cookie可以共享
cookie的特点和作用
cookie存储数据在客户端浏览器
- 浏览器对于单个cookie 的大小有限制(4kb) 以及 对同一个域名下的总cookie数量也有限制(20个)
作用
- cookie一般用于存出少量的不太敏感的数据(数据不安全)
- 在不登录的情况下,完成服务器对客户端的身份识别
案例记录上一次登录时间
protected void doPost(HttpServletRequest request, HttpServletResponse response) thros ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
//先获取cookies
cookie[] cookies = request.getcookies();
boolean flag=false;//是否有请求头last_time
if(cookies.length>0&&cookies!=null){
for (cookie cookie : cookies) {
if("lasttime".equals(cookie.getName())){
//如果条件成立,说明该用户之前登录过
String value = cookie.getValue();//获取日期数据 请求头cookie内的数据
value=URLDecoder.decode(value,"utf-8");//url解码
flag=true;
Date date = ne Date();
SimpleDateFormat format = ne SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
String ne_date = format.format(date);//本次登录的时间字符串
ne_date=URLEncoder.encode(ne_date,"utf-8");//对字符串进行编码
cookie.setValue(ne_date);
cookie.setMaxAge(6030);
response.addcookie(cookie);//将其添加进浏览器 响应头set-cookie 内的数据
response.getWriter().println("上次登录时间"+value);
}
}
}
if (flag==false){//标志为false 表示登录
Date date = ne Date();
SimpleDateFormat format = ne SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
String ne_date = format.format(date);
ne_date=URLEncoder.encode(ne_date,"utf-8");
cookie cookie = ne cookie("lasttime", ne_date);
cookie.setMaxAge(6030);
response.addcookie(cookie);
response.getWriter().println("欢迎你登录!!!!!!");
}
}
- URLDecoder.decode();URL解码
- URLEncoder.encode();URL编码
Session:服务器端会话技术
原理
客户端第一次发出请求(第一次获取session),服务器在内存中会创建一个新的Session对象,并且将响应头JSESSIONID传送到客户端浏览器中
客户端第二次发出请求,请求时会携带请求头JSESSIONID,也就确保了服务器在一次会话范围内,多次获取session对象是同一个
session的实现是依赖域cookie的
常用API
- HttpSession session = request.getSession(); 获取Session
使用HttpSession对象
- Object getAttribute(String name)
- void setAttribute(String name, Object value)
- void removeAttribute(String name)
//session1
protected void doPost(HttpServletRequest request, HttpServletResponse response) thros ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
HttpSession session = request.getSession();//建立Session对象
session.setAttribute("name","Bob");//添加数据
}
//session2
protected void doPost(HttpServletRequest request, HttpServletResponse response) thros ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
HttpSession session = request.getSession();
Object name = session.getAttribute("name");//获取数据
System.out.println(name);
}
注意
当客户端关闭后,服务器不关闭,两次获取session是否为同一个?
默认情况下。不是。
如果需要相同,则可以创建cookie,键为JSESSIONID,设置最大存活时间,让cookie持久化保存。
protected void doPost(HttpServletRequest request, HttpServletResponse response) thros ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
HttpSession session = request.getSession();
cookie cookie = ne cookie("JSESSIONID", session.getId());//持久化请求头JSESSIonID
cookie.setMaxAge(605);
response.addcookie(cookie);
System.out.println(session);
}
客户端不关闭,服务器关闭后,两次获取的session是同一个吗?
不是同一个,要确保数据不丢失。tomcat自动完成以下工作
- session的钝化在服务器正常关闭之前,将session对象序列化到硬盘上
- session的活化在服务器启动后,将session文件转化为内存中的session对象即可
session什么时候被销毁
- 服务器关闭
- session对象调用invalidate() 。
- session默认失效时间 30分钟
30
session的特点
- session用于存储一次会话的多次请求的数据,存储在服务器端
- session可以存储任意类型,任意大小的数据(数据相较于cookie安全)
案例验证码
- 验证码字符串通过session进行存储
- 校验失败,跳转到登录页面,错误提示通过request进行存储
- 校验成功,重定向到成功页面,用户信息通过session进行存储
@WebServlet("/login")
public class login extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) thros ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
request.setCharacterEncoding("utf-8");
//获取数据
String username = request.getParameter("username");
String passord = request.getParameter("passord");
String code = request.getParameter("code");
//判断语句
String session_code = (String) request.getSession().getAttribute("code");
if(code.equalsIgnoreCase(session_code)){
//验证码通过校验
if("tom".equals(username)&&"123".equals(passord)){
//用户密码验证成功
request.getSession().setAttribute("suess_name",username);
response.sendRedirect("/test/suess.jsp");
}else {
//用户名密码错误
request.setAttribute("error_1","用户名密码错误");
request.getRequestDispatcher("/login.jsp").forard(request,response);
}
}else {
//验证码错误
request.setAttribute("error_2","验证码错误");
request.getRequestDispatcher("/login.jsp").forard(request,response);
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) thros ServletException, IOException {
doPost(request, response);
}
}
%@ page contentType="text/html;charset=UTF-8" language="java" %>
登录页面
<%= request.getAttribute("error_1") != null ? request.getAttribute("error_1") : " "%>
<%= request.getAttribute("error_2") != null ? request.getAttribute("error_2") : " "%>