zoukankan      html  css  js  c++  java
  • JSP的隐式对象(session)

    1.session是什么

    • session是服务端为每个用户创建的session对象,在会话期间(可以有多个请求和响应)可以共享存放在session中的数据。
    • 服务端为每个用户创建不同的session对象,使用SessionID来区分不同的客户,session对象在页面之间共享其存储的数据。
    •  一个session的建立是从一个用户向服务器发第一个请求开始,而以用户显式结束或session超时为结束。
    • session是HttpSession接口的一个实例。

     2.session是如何创建的

     当用户发起第一次请求时,服务器自动创建session,并为其创建一个唯一的sessionid,在随后用户与服务器端的多次请求或响应的过程中都使用这个sessionid标识该用户。

    3.session是如何维持的

     服务端通过三种方式维持session会话

    3.1 指定一个唯一的sessionID作为cookie来代表每个客户端,用来识别这个客户端接下来的请求。优点:简单方便,

     在谷歌浏览器中可以查看所有cookie的存放地址和内容

     

     只要不关闭浏览器,服务端的SESSIONID与客户端的JSESSIONID这个键值对就是一样的,服务端就以此来识别是否是同一个用户。

    3.2发送一个隐藏的HTML表单域和一个唯一的session ID。

    <input type="hidden" name="sessionid" value="B9A55B6DF01250337F52425C13BDA2FC">

    3.3(url重写)在每个URL后面添加一些额外的数据来区分会话,服务器能够根据这些数据来关联session标识符。

    http://localhost:8080/index.jsp;jsessionid=5AC6268DD8D4D5D1FDF5D41E9F2FD960?param=3&a=1。

    注意:url后面的;jsessionid用分号来分隔的。

     URL重写功能,为了防止一些用户把Cookie禁止而无法使用session而设置的功能.jsessionid后面的一长串就是你服务器上的session的ID号,这样无需cookie也可以使用session. 

    4.session是如何删除的(会话结束)

    • 程序调用HttpSession.invalidate()
    • 客户端距离上一次收到sessionid的时间间隔超过了session的最大有效时间
    • 服务器进程被停止

     简单例子1——用户登录

     Login.jsp

    <%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" import="java.util.*"%>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>用户登录界面</title>
    </head>
    <body>
    <h2>用户登录</h2>
    <form action="CheckLogin.jsp" method="post">
    <table>
    <tr>
    <td>用户名:</td><td><input type="text" name="username" value="<%=request.getSession().getAttribute("uname") %>"></td>
    </tr>
    <tr>
    <td>密码:</td><td><input type="text" name="password" value="<%=request.getSession().getAttribute("upwd") %>"></td>
    </tr>
    <tr>
    <td colspan="2"><input type="submit" value="提交"></td></td>
    </tr>

    </table>

    </form>

    <%="sessionID:"+request.getSession().getId() %><br>
    <%="session对象被创建的时间:"+(new Date(request.getSession().getCreationTime())).toString() %><br>
    <%="session失效时间:"+request.getSession().getMaxInactiveInterval() %><br>
    <%="当前用户:"+request.getSession().getAttribute("uname") %><br>
    <%="最后访问时间"+(new Date(request.getSession().getLastAccessedTime())).toString() %>
    </body>
    </html>

    CheckLogin.jsp

    <%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>登录验证</title>
    </head>
    <body>
    <%
    //设置编码方式
    request.setCharacterEncoding("utf-8");
    //获得登录的用户名和密码
    String username=request.getParameter("username");
    String password=request.getParameter("password");

    if(username.equals("admin")&&password.equals("123"))
    {
    //验证通过,创建session对象
    session.setAttribute("uname",username);
    session.setAttribute("upwd",password);
    //获得sessionID,并将session在控制台输出
    System.out.println("sessionID:"+session.getId());
    response.sendRedirect("Main.jsp");
    }else{
    response.sendRedirect("Login.jsp");
    }

    %>
    </body>
    </html>

    Main.jsp

    <%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>欢迎登录</title>
    </head>
    <body>
    欢迎您:
    <%
    String name=(String)session.getAttribute("uname");

    if(name==null){
    response.sendRedirect("Login.jsp");

    }else {
    out.println(name);
    }
    %>
    <a href="LoginOut.jsp">注销</a><br>
    <%="sessionID:"+request.getSession().getId() %><br>
    </body>
    </html>

    LoginOut.jsp

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>注销处理</title>
    </head>
    <body>
     <%
             session.invalidate();//session失效
             response.sendRedirect("Login.jsp");
             //session.removeAttribute("uname");//移除指定的属性
    %>
    </body>
    </html>

     第一次访问的时候就可以获取Sessionid,在Login.jsp页面显示,与是否登录成功无关

     输入用户名和密码登录成功后跳转到CheckLogin.jsp页面,此时控制台打印的sessionid与Login.jsp页面是一样的。也就是说同一个用户,session创建后,多次请求和响应时传送的sesssid都是一样的。

    重定向到Main.jsp页面

    登录成功后,后退到Login.jsp页面,两个文本框默认显示session保存的用户名和密码。

    回到Main.jsp页面点击注销连接,手动在代码中清除session,清除后跳转回Login.jsp页面

      清除原来的session以后,重新向服务器发出请求,此时的sessionid已经是服务端重新生成的了。

    简单例子2——实现简单购物车功能

    Buy.jsp 商品浏览页,通过勾选商品前的复选框选中商品,在数量的文本框中输入购买数量。

    Processbuy.jsp 购物车商品使用Map<String,Integer>结构存储,并存入session域对象。

    Show.jsp 提取session域对象中的值,并在页面显示。

    Buy.jsp

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>商品列表</title>
    </head>
    <body>
    <h2 align="center">商品列表</h2>
        <div align="center">
          <form action="Processbuy.jsp" method="post">
            <table border="0" cellspacing="10">
              <tr>
                <th>商品名称</th>
                <th>购买</th>
                <th>价格</th>
                <th>数量</th>
              </tr>
              <tr>
                  <td>笔记本</td>
                <td><input type="checkbox" name="item" value="computer"></td>
                <td>¥5000</td>
                <td><input type="text" name="comnum" value="1" style=" 25px"></td>
              </tr>
              <tr>
                  <td>汽车</td>
                <td><input type="checkbox" name="item" value="car"></td>
                <td>¥200000</td>
                <td><input type="text" name="carnum" value="1" style=" 25px"></td>
              </tr>
              <tr>
                  <td>香水</td>
                <td><input type="checkbox" name="item" value="flower"></td>
                <td>¥500</td>
                <td><input type="text" name="fnum" value="1" style=" 25px"></td>
              </tr>
              <tr>
                  <td>书籍</td>
                <td><input type="checkbox" name="item" value="book"></td>
                <td>¥20</td>
                <td><input type="text" name="bnum" value="1" style=" 25px"></td>
              </tr>
            </table>
            
            <input type="submit" value="购买">      
          </form>
        </div>
    
    </body>
    </html>

    Processbuy.jsp

    <%@page import="java.util.HashMap"%>
    <%@page import="java.util.Map"%>
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
    <%
     String path = request.getContextPath()+"/ShoppingCart";
     String basePath = request.getScheme() + "://"
       + request.getServerName() + ":" + request.getServerPort()
       + path + "/";
     String url = basePath+"Buy.jsp";
    %>
    <%
    request.setCharacterEncoding("utf-8");
    
    Map<String,Integer> map1 =(Map<String,Integer>)session.getAttribute("map1");
    
    if(map1 == null){
        map1 = new HashMap<String, Integer>();
        map1.put("笔记本", 0);
        map1.put("汽车", 0);
        map1.put("香水", 0);
        map1.put("书籍", 0);
    }
    
    
    String[] buys = request.getParameterValues("item");
    //判断是否勾选了复选框
    if(buys==null)
    {
      out.print("请勾选商品信息!");
      //实现页面自动跳转
      response.addHeader("Refresh","2;URL="+url);
      return;
    }
    for(String item:buys)
    {
      if(item.equals("computer"))
      {
          int num1 = map1.get("笔记本").intValue();
          int comnum = Integer.parseInt(request.getParameter("comnum"));
          map1.put("笔记本",num1+comnum);
      }
      else if(item.equals("car"))
      {
          int num1 = map1.get("汽车").intValue();
          int carnum = Integer.parseInt(request.getParameter("carnum"));
          map1.put("汽车",num1+carnum);
      }
      else if(item.equals("flower"))
      {
          int num1 = map1.get("香水").intValue();
          int fnum = Integer.parseInt(request.getParameter("fnum"));
          map1.put("香水",num1+fnum);
      }
      
      else
      {
          int num1 = map1.get("书籍").intValue();
          int bnum = Integer.parseInt(request.getParameter("bnum"));
          map1.put("书籍",num1+bnum);
      } 
      
    
    }
    
    session.setAttribute("map1", map1);
    request.getRequestDispatcher("Show.jsp").forward(request, response);
    %>
    </body>
    </html>

    Show.jsp

    <%@page import="java.util.Map"%>
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>商品结算</title>
    </head>
    <body>
    <h2>结算</h2>
    <%
    Map<String,Integer> map1 = (Map<String,Integer>)session.getAttribute("map1");
    %>
    <table border="0" cellspacing="30">
              <tr>
                <th>商品名称</th>
                <th>数量</th>
                <th>总价</th>
              </tr>
              <tr>
                  <td>笔记本</td>
                <td><%=map1.get("笔记本") %></td>
                <td><%=map1.get("笔记本") %>*5000</td>
              </tr>
              <tr>
                  <td>汽车</td>
                <td><%=map1.get("汽车")%></td>
                <td><%=map1.get("汽车")%>*200000</td>
              </tr>
              <tr>
                  <td>香水</td>
                <td><%=map1.get("香水")%></td>
                <td><%=map1.get("香水")%>*500</td>
              </tr>
              <tr>
                  <td>书籍</td>
                <td><%=map1.get("书籍") %></td>
                <td><%=map1.get("书籍") %>*20</td>
              </tr>
            </table>
            <p>总金额:<%=map1.get("笔记本")*5000+map1.get("汽车")*200000+map1.get("香水")*500+map1.get("书籍")*20 %></p>
            <p><a href="Buy.jsp">继续购买</a></p>
            
            
    </body>
    </html>

    运行截图:

    选中商品,点击购买,结算如下显示:

     

     点击继续购买,保留之前购买的数量,合并结算:

     

    参考文章:

    https://www.runoob.com/jsp/jsp-session.html

    https://www.cnblogs.com/shenbing/p/5372717.html

     https://www.cnblogs.com/zhaoYuQing-java2015/p/4621384.html

    https://www.cnblogs.com/ym77/p/11323742.html

    https://blog.csdn.net/collonn/article/details/5698906

    https://blog.csdn.net/qq_35756383/article/details/81632119 

    转载文章链接已标明,如有侵权请告知。文章仅作为知识记忆所用,如有错误,敬请指正。
  • 相关阅读:
    大型网站的数据库分割问题。
    大型网站的数据库分割问题。
    分布式集群的Session问题
    大型网站架构设计摘要
    大型网站的架构概要
    公司产品的优势
    java.util.concurrent 学习笔记(2) 线程池基础
    《Java 7 并发编程指南》学习概要 (6) Fork/Join
    《Java 7 并发编程指南》学习概要 (5) 线程池
    《Java 7 并发编程指南》学习概要 (4) 并发集合
  • 原文地址:https://www.cnblogs.com/YorkZhangYang/p/12444584.html
Copyright © 2011-2022 走看看