会话管理技术概述
1.什么是会话
这里的会话指的是web开发中的一次通话过程,当打开浏览器,访问网站地址后,会话开始,当关闭浏览器(或者到了过期时间),会话结束。
2.会话管理技术能做什么
共享同一个客户浏览器多个请求中数据,例如过滤。
客户端会话管理技术 (Cookie)
1.什么是Cookie?
它是客户端浏览器的缓存文件,里面记录了客户浏览器访问网站的一些内容,它是http协议请求和响应消息头的一部分。
2.Cookie能做什么?
能保存客户浏览器访问网站的相关内容(需要服务器开启Cookie)。从而在每次访问需要同一个内容时,先从本地缓存获取,使资源共享,并且提高效率。
3.Cookie中的属性
name:必要属性,cookie的名称
value:必要属性,cookie的值
path:cookie的路径
domain:cookie的域名,相当于访问的网站(localhost)
maxAge:cookie的生存时间(>0硬盘cookie;<0内存cookie;=0追杀cookie
version:cookie版本号(不重要)
comment:cookie的说明(不重要)
4.案例
保存用户名
package cn.itheima.username;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 登陆界面类
* @author LBK
*
*/
public class UserSaveUI extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
String username="";
String ischk="";
Cookie cs[]=request.getCookies();
for(int i=0;cs!=null&&i<cs.length;i++){
if("userinfo".equals(cs[i].getName())){
username=cs[i].getValue();
ischk="checked";
}
}
//表单方式界面布局
out.write("<form action='"+request.getContextPath()+"/LoginUserNameSave' method='post'>");
out.write("用户名:<input type='text' name='username' value='"+username+"' /><br/>");
out.write("<input type='checkbox' name='remember' "+ischk+" />记住用户名<br/> ");
out.write("<input type='submit' value='登录' />");
out.write("</form>");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
}
}
package cn.itheima.username;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 保存cookie的类
* @author LBK
*
*/
public class LoginUserNameSave extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
//获取UI端发送过来的请求
String username=request.getParameter("username");
String remember=request.getParameter("remember");
//判断用户名是否为空
if("".equals(username)||username==null){
out.write("用户名不能为空,2秒后返回登陆页");
response.setHeader("Refresh", "2;URL="+request.getContextPath()+"/UserSaveUI");
return;
}
//如果存在将username存入cookie
Cookie cookie=new Cookie("userinfo",username);
if(remember==null||"".equals(remember)){
cookie.setMaxAge(0);
}else{
cookie.setMaxAge(Integer.MAX_VALUE);
}
//返回给客户端cookie
response.addCookie(cookie);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// response.setContentType("text/html");
// PrintWriter out = response.getWriter();
doGet(request, response);
}
}
服务端会话管理技术
1. 什么是HttpSession
它是一个服务端会话对象,存储用户的会话数据.
2. HttpSession的生命周期
出生--活着--死亡
出生:调用getSession方法后会话开始
活着:只要没有关闭会话或者调用立即消失的方法.或者服务器意外,HttpSession一直存在
死亡:立即消失,到了过期时间,服务器意外
3. 域对象(三缺一)
HttpSession:也是一个域对象,它比application域范围小,比request域范围大
4. 案例
防止重复提交
package cn.itheima.form;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;
import java.util.UUID;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionContext;
/**
* 界面类
* 生成界面,生成令牌
* @author LBK
*
*/
public class UI extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
//生成一个令牌
String token=UUID.randomUUID().toString();
//创建一个session 将UUID放到里面
HttpSession s=request.getSession();
s.setAttribute("stoken", token);
//绘制界面
out.write("<form action='"+request.getContextPath()+"/Tran' method='post' >");
out.write("设置转账金额:<input type='text' name='money' /><br/>");
//添加一个隐藏域,存放令牌
out.write("<input type='hidden' name='ftoken' value='"+token+"' />");
out.write("<input type='submit' value='转账' />");
out.write("</form>");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
package cn.itheima.form;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
* 根据得到的令牌判断是否在进行重复提交操作
* @author LBK
*
*/
public class Tran extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
String money=request.getParameter("money");
String ftoken=request.getParameter("ftoken");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
HttpSession s=request.getSession();
String stoken=(String) s.getAttribute("stoken");
if(ftoken.equals(stoken)){
out.write("转账成功!"+money);
s.removeAttribute("stoken");
}else{
out.write("请不要重复提交!");
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
5. 用户端禁用Cookie后会话数据的保持
方式一:使用文字提示.163邮箱就是使用的这种方式
方式二:URL重写
解释:当禁用了cookie之后,客户端永远都不会带cookie到服务器.
解决:我们自己给他戴上,把URL重写.拼上一个JSESSIONID=session的ID.
使用的是response.encodeURL()方法
原来:http://localhost:8080/servletdemo/ServletDemo1
现在:http://localhost:8080/servletdemo/ServletDemo1;JSESSIONID=123
6. HttpSession对象的状态
a.什么是持久化
把长时间不用,但还不到过期时间的HttpSession进行序列化,写到磁盘上.我们把HttpSession持久化也叫做钝化.(与钝化相反的是活化)
b.什么时候使用持久化
第一种情况:当访问量很大时,服务器会根据getLastAccessTime来进行排序,对长时间不用,但是还没到过期时间的HttpSession进行持久化.
第二种情况:当服务器进行重启的时候,为了保持客户的HttpSession中的数据,也要对HttpSession进行持久化.