会话技术

会话技术【 cookie 与 session】
会话技术概述
什么是会话技术?  人与人聊天,叫是会话!
浏览器与服务器的会话:
打开浏览器,访问服务器,在关闭浏览器浏览器之前,这就是一次会话!

打开浏览器,
访问服务器1次,
访问服务器2次,
访问服务器n次,
只要浏览器没有关闭,这就是一次会话,且还在进行中!
什么时候会话结束? 浏览器关闭,表示会话结束!
会话技术:
Cookie   客户端的会话技术
Session  服务器端的会话技术 (session的原理是基于cookie)


2. Cookie 
Cookie概述
客户端会话技术,数据可以保存在cookie中,即保存在客户端浏览器中!
保存:
1. 保存在浏览器进程中,浏览器已关闭,数据就没有了!(cookie默认)
2. 保存在浏览器的缓存文件目录下
需要设置cookie有效时间(cookie.setMaxAge(秒));
Cookie Api
response,  响应对应, 用于设置响应信息的!
response对象方法:
void addCookie(Cookie cookie)   在响应中添加一个cookie信息


response.addCookie(cookie_cn);    添加cookie 【set-cookie】
Cookie[] cs = request.getCookies();  // 获取cookie 【获取cookie信息】

设置cookie对象的相关信息常用方法:
void setMaxAge(int expiry)      设置有效时间,没有设置关闭浏览器数据就不存在

void setPath(    设置cookie的有效路径

void setDomain(  设置域名(访问哪个网站时候带cookie信息)

Cookie总结:
1. cookie 数据数存储到客户端浏览器的;  不安全!
2. 数据虽然存储到客户端浏览器,但是需要从服务器发送数据到浏览器
  (设置set-cookie响应头)
3. 浏览器最多支持300个cookie,每个网站最多支持20个cookie
(限制目录,提升访问效率,减少服务器压力 )
4. cookie中数据不能有特殊符号(@)、中文
    Cookie c =  new Cookie("lastAccessTime", URLEncoder.encode("", "utf-8"));
 再次获取数据的时候,需要手动解码
 URLDecoder.decode(s, enc);
 URLEncoder.encode(s, enc);   编码
 URLDecoder.decode(s, enc);   解码
Cookie 简单案例
设置cookie信息
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 1. 创建Cookie对象
Cookie cookie_cn = new Cookie("cn", "China");
Cookie cookie_usa = new Cookie("usa", "America");
// 2. 把cookie添加到response响应中,这样cookie数据就会发送给浏览器了 【响应头: set-cookie】
// 接着,再此访问服务器,会带着cookie的数据访问服务器
response.addCookie(cookie_cn);
response.addCookie(cookie_usa);
}
获取Cookie信息
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {

// 方式1:获取cookie信息
String str = request.getHeader("Cookie");  //cn=China; usa=America
System.out.println(str); // cn=China

// 方式2: request有提供获取cookie信息的方法
Cookie[] cs = request.getCookies();        // 请求头数据封装为一个个对象 
// 先判断
if (cs != null && cs.length > 0) {
// 再遍历,得到每一个cookie对象
for (Cookie c : cs) {
String name = c.getName();
String value = c.getValue();
System.out.println(name + "=" + value);
}
}
}


Cookie 案例1: 

public class CookieTimeServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 设置响应数据的编码
response.setContentType("text/html;charset=UTF-8");
// write对象
PrintWriter out = response.getWriter();
// 0. 先从cookie中获取上次访问的时间
// 从请求中获取访问的所有cookie
Cookie[] cs = request.getCookies();
if (cs != null && cs.length >0) {
for (Cookie cookie : cs) {
// 获取保存到cookie中的key  【cn=China; usa=America】
String key = cookie.getName();
// 判断
if ("lastAccessTime".equals(key)) {
// 获取值
String value = cookie.getValue();
// 输出
out.write("上次访问时间是: " + value + "
");
break;
}
}
}
// 1. 获取当前时间,输出到浏览器
String date = new Date().toLocaleString();
out.write("当前时间:" + date);
// 2. 保存当前时间到cookie中 (再次访问,这个时间就是上次访问时间)
Cookie c = new Cookie("lastAccessTime", date);
// 设置有效目录
c.setPath("/day10");
// 设置有效时间
c.setMaxAge(300);
// 设置到response对象中, 通过response对象发送给浏览器cookie信息
response.addCookie(c);

}

}


Cookie 案例2: 

public class GoodServlet extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {

response.setContentType("text/html; charset=UTF-8");
PrintWriter out = response.getWriter();

// 一. 查询所有的商品
GoodDao dao = new GoodDao();
List list = dao.getAll();
// 通过resposne对象,向浏览器输出数据
out.write("编号      商品名称   价格   折扣价");
out.write("  操作
");
for (Good g : list) {
out.write(g.getId() + "  ");
out.write(g.getGoodName() + "  ");
out.write(g.getPrice() + "  ");
out.write(g.getDisPrice() + "  ");
out
.write("查看");
out.write("
");
}

// 四、显示历史记录

// 从cookie中获取历史记录: 1,2,3
Cookie[] cs = request.getCookies();
if (cs != null && cs.length > 0) {
// 保存从cookie中获取的历史记录的id
String historyId = "";

for (Cookie cookie : cs) {
String name = cookie.getName();
if ("historyId".equals(name)) {
historyId = cookie.getValue();
break;
}
}

// 显示商品
// a. 分割字符串, 得到每一个id
String ids[] = historyId.split(",");
if (ids != null && ids.length > 0) {
out.write("

历史记录:
");
for (int i = 0; i < ids.length; i++) {
// 获取每一个编号
int id = Integer.parseInt(ids[i]);
// 根据编号查询商品
Good good = dao.findById(id);
out.write(good.getId() + "  ");
out.write(good.getGoodName() + "
");
}
}

}

}

}




public class GoodDetailServlet extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {

response.setContentType("text/html; charset=UTF-8");
PrintWriter out = response.getWriter();
//二、显示列表商品
//  获取id
String id = request.getParameter("id");
//  根据id查询
GoodDao dao = new GoodDao();
Good g = dao.findById(Integer.parseInt(id));
// 显示商品
out.write("商品名称: " + g.getGoodName() + "
");
out.write("商品价格: " + g.getPrice() + "
");
out.write("折扣价格: " + g.getDisPrice() + "
");
out.write("
回到列表");
// 三、保存访问的历史记录到cookie中
String value = getHistoryId(request,id);   //存储的是商品的编号:如 3,1,2
Cookie c = new Cookie("historyId", value);
c.setPath("/day10");
//c.setMaxAge(300);
// 发送给浏览器
response.addCookie(c);
}

// 拼接历史记录的id
private String getHistoryId(HttpServletRequest request, String id) {
// 保存历史记录
String histroy_id = "";
// 先从request中获取所有的cookie
Cookie[] cs = request.getCookies();
if (cs != null && cs.length > 0) {
for (Cookie cookie : cs) {
// 获取历史记录的cookie
String name = cookie.getName();
if ("historyId".equals(name)) {
// 有历史记录
histroy_id = cookie.getValue();
break;
}
}
}
System.out.println();
// 第一次访问, 历史记录只有当前id
if (histroy_id == "") {
return id;
}
// 如果不是第一次访问,需要把当前的id,拼接到历史记录中(histroy_id)
String[] ids = histroy_id.split(",");  // 获取历史记录中的所有id
// 创建集合,保存数组中数据
LinkedList list = new LinkedList();
// 把数组中数据拷贝到list集合
for (int i=0;i
list.add(ids[i]);
}
// 拼接历史记录
if (ids.length < 3) {
// 如果历史记录不够3个,就直接添加到集合第一个元素
list.addFirst(id);
} else {
// 判断: 当当前查看的编号在历史记录中存在,  就删除当前id,再把id添加到集合第一个元素
if (list.contains(id)){
list.remove(id);
list.addFirst(id);
} else {
list.removeLast();   // 先删除最后
list.addFirst(id);   // 在把当前编号添加到集合的第一个元素中
}
}
// 处理集合数据,最终得到"1,2,3" 编号
StringBuffer sb = new StringBuffer();
for (int i=0;i
sb.append(list.get(i) + ",");
}
// 去掉最后的逗号
String result = sb.substring(0,sb.length()-1);
return result;
}

}




3. Session
Session概述
Session 表示会话对象; 服务器的会话对象!
HttpSession getSession()     从request对象中可以获取Session对象!

如何存储用户的数据?
用户输入
用户名(XX)、密码---》 
登陆---》 
后台验证:…..  ----》   (数据如何保存?request? ServletContext?)
首页index.jsp
欢迎你,XX!

解决:
用户的数据,存储:
request:  整个项目都要用转发,不可能!   (小)
ServletContext:   用户名都存储到Servletcontext中,极易被覆盖!  (大)
最终,
Session:  会话对象,可以保存用户的数据! (中)
范围: 
打开浏览器,访问服务器,多次访问服务器,用的是一个会话!
SessionAPI
获取session:
request.getSession();    第一次执行时候创建session对象;
如果浏览器没有关闭,再次访问,就获取session
request.getSession(true);  同上
request.getSession(false);  不创建session,会获取已经创建的session; 如果之前
 没有创建session,就返回null

域对象:
request.setAttribute(key,value);
request.getAttribute(key);
request.removeAttribute(key);
域对象总结:
域对象范围由小到大:
Request   <   session    <  servletContext

存储购物列表、登陆用户?  - session

思考:
服务器,如何区分当前的多个访问是否是同一个session?
(session原理)
1. 服务器在第一次执行request.getSession() 创建session对象
   a. 服务器生成一个唯一的sessionId;
b. 服务器存储id
c. 把id通过response对象发送给浏览器
(设置set-cookie相应头)
Set-Cookie:JSESSIONID=5A15565F22803450A0E60D08F229EC03; Path=/day10
2. 浏览器没有关闭,再次访问,会带着cookie头,访问服务器
Cookie:JSESSIONID=AF91F6C7CC978A1D0520F7D76BC49455
3. 服务器获取浏览器带过来的sessionId, 且获取服务器生成的id
如果相等,说明是同一个session!
总结:
Session存储基于cookie技术!


其他 
int getMaxInactiveInterval() ; 获取session的最大活跃时间
void setMaxInactiveInterval(int interval)   设置sesison的最大活跃时间
建议使用配置的方式修改最大活跃时间

关于活跃时间:
Session的最大活跃时间默认为30分钟!
活跃时间:只有在活跃时间范围内使用,就会从新计算,再使用指定的默认时间!
查看session最大活跃时间的默认设置:
Tomcat/conf/web.xml
        30    分钟
   
如果修改:
/tomcat/webapps/day10/WEB-INF/web.xml
如果在自己的项目中进行了修改,会覆盖服务器默认的配置!

 如何解决浏览器关闭,session中数据丢失问题?
方案:
手动设置set-cookie的有效时间!
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 获取session
// Set-Cookie:JSESSIONID=0AC179863C7421C181E8677E56D5F9EA; Path=/day10
HttpSession session = request.getSession();
// 获取sessionid, 作为相应头的值
String id = session.getId();
// 创建cookie
Cookie cookie = new Cookie("JSESSIONID", id); 
cookie.setPath("/day10");
cookie.setMaxAge(300);  // 设置有效时间(5分钟)
// 设置响应的cookie对象
response.addCookie(cookie);
// 往session域(会话域)中保存数据
session.setAttribute("userInfo", "Jie.Yuan");
}


问题:
1. 浏览器关闭后,session有没有销毁!
浏览器关闭后,session不一定销毁!
如果关闭时候,刚好达到最大活跃时间,就销毁!
2. session什么时候销毁?
情况1: 达到最大活跃时间的时候,服务器会销毁session!
调用void invalidate()  销毁session!
情况2:手动调用: void invalidate()  
“注销”
session.removeAttribute("");
session.invalidate();

会话技术为什么产生,有哪些应用?
会话技术是保存当前用户与浏览器的通讯的数据的!
应用:保存当前登陆用户、保存当前用户购买的所有商品!
如果想获取转发后的数据,用request域
request.setAttribute(..);
如果想获取重定向后的数据,用session域
session.setAttribute(..);

1. cookie 会用, 结合http协议!
2. session要回用 session.setAttribute(..); (与cookie有关、设置的数据在什么情况可以获取?)
3. session原理 服务器如何区分不同的用户(不同的session) ? (结合cookie)
4. cookie 练习
5. session
a. 登陆(读取xml)
b. 登陆后,显示列表
c. 列表查看
d. 显示历史记录(cookie)
e. 列表商品,添加到购买集合中,再在浏览器显示购买的集合
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值