Cookie和Session

HTTP会话管理
本文介绍HTTP协议中的会话管理技术,包括Cookie和Session的工作原理、使用方法及应用场景。通过示例展示如何实现用户登录状态保持、浏览历史记录等功能。

因为http协议是无状态的,每次都是基于一个请求一个响应.每次请求和响应都跟上次没有关系.
我们需要记录之前对话信息.
cookie技术.是属于客户端(浏览器)保存信息的技术.

让浏览器记住键值对.是向响应头中添加一下头即可:
set-Cookie:name=tom;
浏览器记住之后,向服务器发送键值对,是在请求头中添加下面的信息:
Cookie: name=tom;

这里写图片描述

Cookie使用方式

  1. 新建一个cookie(键值对)
    Cookie cookie = new Cookie(“name”, “tom”);
  2. 将cookie 添加到响应中
    response.addCookie(cookie);
  3. 获得所有浏览器发送的cookie
    Cookie[] cookies = request.getCookies();
  4. 遍历并判断我们要找的cookie
if(cookies!=null && cookies.length>0){
    for(Cookie c : cookies){
            if(c.getName().equals("name")){
                System.out.println("获得的cookie:"+c.getName()+":"+c.getValue());
            }
    }
}
//AServlet
public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        Cookie cookie = new Cookie("name", "tom");  
        response.addCookie(cookie);     
        response.getWriter().print("send cookie successed!");
}
//BServlet
public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {  
    Cookie[] cookies  = request.getCookies();   
    if(cookies!=null && cookies.length>0){
        for(Cookie c : cookies){
                if(c.getName().equals("name")){
                    System.out.println("获得的cookie:"+c.getName()+":"+c.getValue());
                }
        }
    }   
}
//先访问AServlet设置cookie,再设置BServlet获取Cookie
  1. 浏览器记多久?
    默认是在会话期间有效.(关闭浏览器,cookie就被删除).(有效时间-1)
  2. 有效时间如何设置?
    //设置cookie的最大有效时间
    1. 设置一个正数,标示最大有效时间.单位是秒
    //cookie.setMaxAge(60*60);
    2. 设置为-1 , 就是相当于默认有效时间, 浏览器关闭就消失.
    //cookie.setMaxAge(-1);
    3. 标示cookie的有效时间为0.发送到浏览器就消失了.
    //利用有效时间为0 这件事,我们可以做删除cookie的操作.
    // 因为同一个路径 ,不能存在相同的cookie(键相同).
    // 我们可以通过覆盖的方式,设置有效时间为0. 删除cookie
    cookie.setMaxAge(0);

Cookie路径

cookie的默认路径就是发送cookie的servlet所在目录.
访问路径如果是cookie路径的子路径那么,浏览器就会把该cookie告诉服务器.
例如通过/EServlet设置cookie,再次访问EServlet会将cookie添加到请求头中,访问/EServlet/xxx也会将cookie添加到请求头中,但是访问/xxx则不会

浏览历史(例子)

CServlet
public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //1 获得当前访问的品牌
        String current = request.getParameter("name");
        //2 获得之前访问过的品牌(获得cookie)
        Cookie history = null;
        Cookie[] cookies = request.getCookies();
        if(cookies!=null && cookies.length>0){
            for(Cookie c: cookies){
                if(c.getName().equals("history")){
                    history = c;
                }
            }
        }
        //3 将当前访问 加上 之前访问的,创建一个新的cookie.
        // "history" = "dell,apple,hasee"
        String value = "";
        if(history!=null){          
            value = history.getValue();
            if(!history.getValue().contains(current)){ //判断当前访问的是否 之前已经访问过
                value +=","+current;
            }
        }else{//没有获得到之前的cookie,说明是第一次访问.
            value = current;
        }
        Cookie newHistory = new Cookie("history",value);    
        //4 将cookie添加到响应中
        response.addCookie(newHistory);
        //5 将商品记录 放置到request域中
        request.setAttribute("history",value);
        //6 转发到jsp显示
        request.getRequestDispatcher("/history/list.jsp").forward(request, response);
}
  <body>
        <a href="<%=request.getContextPath() %>/CServlet?name=dell" >dell</a> <br>
        <a href="<%=request.getContextPath() %>/CServlet?name=lenovo" >lenovo</a><br>
        <a href="<%=request.getContextPath() %>/CServlet?name=apple" >apple</a><br>
        <a href="<%=request.getContextPath() %>/CServlet?name=acer" >acer</a><br>
        <a href="<%=request.getContextPath() %>/CServlet?name=hasee" >hasee</a><br>
        浏览历史:
            <%=request.getAttribute("history") %>
  </body>

这里写图片描述

记住用户名

<!--Login.jsp-->
<%
    //1 获得浏览器发送 过来的cookie
Cookie[] cookies = request.getCookies();
    //2 遍历找到保存用户名的
    Cookie remeber = null;
            if(cookies!=null && cookies.length>0){
                for(Cookie c: cookies){
                    if(c.getName().equals("remeber")){
                        remeber = c;
                    }
                }
            }
    //3 如果找到取得它的值
    //4把值设置到 用户名所在input
 %>
<body>
<form action="/MyTestProject/FServlet"  method="post"  >
  用户名:  <input type="text" name="name"  value="<%=remeber==null?"":remeber.getValue() %>" /><br>
   密码:  <input type="password" name="password" /><br>
  记住用户名(一周):    <input type="checkbox" name="remeber" value="yes" <%=remeber==null?"":"checked" %> /><br>
    <input  type="submit" value="登录" /> <br>
   </form>
</body>

<!--index.jsp-->
<body>
  This is my JSP page. <br>
</body>
//DServlet
public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //1 获得用户名
    String name= request.getParameter("name");
    String remeber = request.getParameter("remeber");
        //新建cookie
    Cookie cookie = new Cookie("remeber",name);
        //2判断remeber .
    if(remeber!=null && remeber.equals("yes")){
        // "yes" 勾选了 ==>  设置有效时间为 一周
        cookie.setMaxAge(60*60*24*7);
    }else{
        // null 没勾选 ==>  设置cookie的有效时间为0
        cookie.setMaxAge(0);
    }
        //3 将cookie添加到response
    response.addCookie(cookie);
        //4 跳转到成功页面
    request.getRequestDispatcher("/index.jsp").forward(request, response);
}

Session

服务器端保存会话信息的技术.
浏览器第一次访问服务器,服务器会在内存中开辟一个空间(session),并把session对应的ID发送给浏览器.
那么下次浏览器再去访问服务器,会把sessionID 交给服务器,服务器通过sessionID 找到刚才开辟的空间.
以上就是session的原理.

Session相关

  1. 服务器让浏览器记住sessionID的cookie 默认过期时间是 (-1)==> 关闭浏览器 cookie就丢失 ==> cookie丢失 sessionID就丢失 ==> 找不到服务器的session
  2. session默认过期时间是30分钟. ==> 在tomcat的web.xml中 配置的.
修改session的过期时间
  1. 修改在tomcat的web.xml中 ==> 影响服务器中的所有项目
  2. 在项目的web.xml中 加入 配置.==> 影响的是当前项目
  3. 通过setMaxInactiveInterval(int interval)方法设置.==> 当前操作的session
操作session方法(除了set,get的四个方法)
  1. long getCreationTime() 获得创建时间
  2. String getId() 获得sessionID
  3. long getLastAccessedTime() 获得最后一次访问时间
  4. int getMaxInactiveInterval() 获得session的过期时间
  5. void setMaxInactiveInterval(int interval) 设置session的过期时间
  6. void invalidate() 让session立即失效
  7. boolean isNew() 查看当前获得session是否是新创建的(第一次获取session的时候是true)

购物车(例子)

这里写图片描述

<!--list.jsp-->
<table border=1 align="center">
    <tr>
        <td><h3>商品名称1</h3><img src="/MyTestProject/img/one.jpg" width="200" height=200><br/><a href="/MyTestProject/BServlet?name=1">加入购物车</a><td>
        <td><h3>商品名称2</h3><img src="/MyTestProject/img/two.jpg" width="200" height=200><br/><a href="/MyTestProject/BServlet?name=2">加入购物车</a><td>

        <td><h3>商品名称5</h3><img src="/MyTestProject/img/five.jpg" width="200" height=200><br/><a href="/MyTestProject/BServlet?name=5">加入购物车</a><td>
    </tr>
    <tr>
        <td><h3>商品名称3</h3><img src="/MyTestProject/img/three.jpg" width="200" height=200><br/><a href="/MyTestProject/BServlet?name=3">加入购物车</a><td>
        <td><h3>商品名称4</h3><img src="/MyTestProject/img/four.jpg" width="200" height=200><br/><a href="/MyTestProject/BServlet?name=4">加入购物车</a><td>
    </tr>
</table>
<!--car.jsp-->
<%
    //1. 获得session
    //2. 从session中取出购物车的map
    Map<String,Integer> map=(Map<String,Integer>)session.getAttribute("car");

%>
<body>
    <h1 align="center">购物车详情</h1>
    <table border=1 align="center">
        <tr>
            <th>商品名称</th>
            <th>商品数量</th>
        </tr>
        <%
            //3.遍历显示
            if(map!=null&&map.size()>0){
                for(Entry<String,Integer> en:map.entrySet()){
                    %>
                    <tr><td><%=en.getKey() %></td><td><%=en.getValue() %></td></tr>
                    <% 
                }
            }else{
                out.print("您还没有添加任何商品");
            }
        %>


    </table>
</body>
//BServlet
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // TODO Auto-generated method stub
    //1.获得要添加的商品(0-4)
    String name=request.getParameter("name");
    int intName=Integer.parseInt(name);
    //2.将数字翻译为中文名称(使用数组)
    String[] products=new String[] {"商品名称1","商品名称2","商品名称3","商品名称4","商品名称5"};
    String productName=products[intName];
    //3.获得session
    HttpSession session=request.getSession();
    //4.获得session中保存的购物车(Map)
    Map<String, Integer>map=(Map<String, Integer>) session.getAttribute("car");
    if(map!=null) {
        //获得到,则不是第一次访问,继续向Map中添加
        Integer count=map.get(productName);
        if(count==null) {
            //不存在,添加并设置为1
            count=1;
        }else {
            //map已存在此商品,数量加1
            count++;
        }
        map.put(productName, count);
    }else {
        //没获得,第一次访问
        map=new HashMap<String,Integer>();
        //创建map,将商品添加并设为1
        map.put(productName, 1);
    }
    //5.将Map操作完放回session
    session.setAttribute("car", map);
    //6.返回到列表页面(重定向)
    response.sendRedirect(request.getContextPath()+"/car/list.jsp");
}

这里写图片描述

这里写图片描述

验证码(例子)

这里写图片描述

ValidateCode.jar 链接: https://pan.baidu.com/s/1mhFdihM 密码: 9est

//login.jsp
<head>
    <script type="text/javascript">
        function fun1(){
            //1  获得img对象
            var img =   document.getElementById("one");
            //2 改变img对象 src属性
                img.src = "/MyTestProject/BServlet?abc="+new Date();    
        }

    </script>
</head>
 <body>
  <form action="/MyTestProject/AServlet"  method="post"  >
 用户名:   <input type="text" name="name"  /><br>
  密码:   <input type="password" name="password" /><br>
 验证码:   <input type="text" name="code"   /><img src="/MyTestProject/BServlet" width="150" id="one" onclick="fun1();" />
            <a href="javaScript:void(0)"  onclick="fun1();"  >看不清换一张</a><br>
    <input  type="submit" value="登录" /> <br>
  </form>
  <font color="red">
    <%=request.getAttribute("error")==null?"":request.getAttribute("error") %>
  </font>
 </body>
//BServlet
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // TODO Auto-generated method stub
    //1.生成验证码
    ValidateCode code=new ValidateCode(200,80,4,100);
    //2. 将验证码保存到session中
    request.getSession().setAttribute("code", code.getCode());
    //3.将验证码图片输出到浏览器 
    response.setContentType("image/jpeg");
    code.write(response.getOutputStream());
}
//AServlet
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // TODO Auto-generated method stub
    //1.获得表单提交的验证码
    String code1=request.getParameter("code");
    //2.获得session中正确的验证码
    String code2=(String) request.getSession().getAttribute("code");
    //3.比对是否一致
    if(code1!=null&&code2!=null&&code1.equals(code2)) {
        //正确
        response.sendRedirect("/MyTestProject/index.jsp");
    }else {
        request.setAttribute("error", "验证码输入错误");
        request.getRequestDispatcher("/checkcode/login.jsp").forward(request, response);
    }
}

这里写图片描述

这里写图片描述

这里写图片描述

URL重写

如果浏览器 禁用cookie功能不能保存任何cookie.那么session技术要是用 cookie来保存sessionID. 没有cookie怎么保存?
使用url重写解决该问题.
将页面中所有的连接 末尾全都加上 cookieid的参数. 这样用户点击连接访问网站,通过url把SeesionID带到了服务器.这样就解决了.但是 互联网行业没有这么干的.

常见问题.

  1. session标示一次会话. 会话的范围?
    1. session的开始 ==> 第一次访问服务器.
    2. 结束 第一: 浏览器关闭.(保存sessionID的cookie默认有效时间是-1)
    第二: 超过session设置的有效时间.默认30分钟. web.xml => <session-config><sessiont-timeout>
  2. session能不能跨项目?
    不能跨项目.
  3. session在一个项目中可以对项目中的任意路径共享数据吗?
    保存sessionID的cookie的路径是 项目==> /Day10
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值