JavaWeb(六):会话与状态管理

HTTP协议是一种无状态的协议,WEB服务器本身不能识别出哪些请求是同一个浏览器发出的 ,浏览器的每一次请求都是完全孤立的。即使 HTTP1.1 支持持续连接,但当用户有一段时间没有提交请求,连接也会关闭。怎么才能实现网上商店中的购物车呢:某个用户从网站的登录页面登入后,再进入购物页面购物时,负责处理购物请求的服务器程序必须知道处理上一次请求的程序所得到的用户信息。
作为 web 服务器,必须能够采用一种机制来唯一地标识一个用户,同时记录该用户的状态。

WEB应用中的会话是指一个客户端浏览器与WEB服务器之间连续发生的一系列请求和响应过程。WEB应用的会话状态是指WEB服务器与浏览器在会话过程中产生的状态信息,借助会话状态,WEB服务器能够把属于同一会话中的一系列的请求和响应过程关联起来。

WEB服务器端程序要能从大量的请求消息中区分出哪些请求消息属于同一个会话,即能识别出来自同一个浏览器的访问请求,这需要浏览器对其发出的每个请求消息都进行标识:属于同一个会话中的请求消息都附带同样的标识号,而属于不同会话的请求消息总是附带不同的标识号,这个标识号就称之为会话ID(SessionID)。
在 Servlet 规范中,常用以下两种机制完成会话跟踪

  • Cookie
  • Session

一、Cookie

cookie机制采用的是在客户端保持 HTTP 状态信息的方案,Cookie是在浏览器访问WEB服务器的某个资源时,由WEB服务器在HTTP响应消息头中附带传送给浏览器的一个小文本文件。一旦WEB浏览器保存了某个Cookie,那么它在以后每次访问该WEB服务器时,都会在HTTP请求头中将这个Cookie回传给WEB服务器。
底层的实现原理: WEB服务器通过在HTTP响应消息中增加Set-Cookie响应头字段将Cookie信息发送给浏览器,浏览器则通过在HTTP请求消息中增加Cookie请求头字段将Cookie回传给WEB服务器。
一个Cookie只能标识一种信息,它至少含有一个标识该信息的名称(NAME)和设置值(VALUE)。一个WEB站点可以给一个WEB浏览器发送多个Cookie,一个WEB浏览器也可以存储多个WEB站点提供的Cookie。浏览器一般只允许存放300个Cookie,每个站点最多存放20个Cookie,每个Cookie的大小限制为4KB。

1.1 Cookie常用API

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" session="false"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>

    <%
        //在 JavaWEB 规范中使用 Cookie 类代表 cookie

        //1. 获取 Cookie
        Cookie [] cookies = request.getCookies();
        if(cookies != null && cookies.length > 0){
            for(Cookie cookie: cookies){
                //2. 获取 Cookie 的 name 和 value
                out.print(cookie.getName() + ": " + cookie.getValue());
                out.print("<br>");
            }
        }else{
            out.print("没有一个 Cookie, 正在创建并返回");
            //1. 创建一个 Cookie 对象
            Cookie cookie = new Cookie("name", "aidata");
            //setMaxAge: 设置 Cookie 的最大时效, 以秒为单位, 若为 0 , 表示立即删除该 Cookie
            //若为负数, 表示不存储该 Cookie, 若为正数, 表示该 Cookie 的存储时间.
            cookie.setMaxAge(30);

            //2. 调用 response 的一个方法把 Cookie 传给客户端.
            response.addCookie(cookie);
        }
    %>

</body>
</html>

Servlet API中提供了一个javax.servlet.http.Cookie类来封装Cookie信息,它包含有生成Cookie信息和提取Cookie信息的各个属性的方法。
Cookie类的方法:

  • 构造方法: public Cookie(String name,String value)
  • getName方法
  • setValue与getValue方法
  • setMaxAge与getMaxAge方法
  • setPath与getPath方法

HttpServletResponse接口中定义了一个addCookie方法,它用于在发送给浏览器的HTTP响应消息中增加一个Set-Cookie响应头字段。
HttpServletRequest接口中定义了一个getCookies方法,它用于从HTTP请求消息的Cookie请求头字段中读取所有的Cookie项。

Cookie的发送

1.创建Cookie对象
2.设置最大时效
3.将Cookie放入到HTTP响应报头
如果创建了一个cookie,并将他发送到浏览器,默认情况下它是一个会话级别的cookie; 存储在浏览器的内存中,用户退出浏览器之后被删除。若希望浏览器将该cookie存储在磁盘上,则需要使用maxAge,并给出一个以秒为单位的时间。将最大时效设为0则是命令浏览器删除该cookie。
发送cookie需要使用HttpServletResponse的addCookie方法,将cookie插入到一个 Set-Cookie HTTP响应报头中。由于这个方法并不修改任何之前指定的Set-Cookie报头,而是创建新的报头,因此将这个方法称为是addCookie,而非setCookie。

会话Cookie和持久Cookie
如果不设置过期时间,则表示这个cookie生命周期为浏览器会话期间,只要关闭浏览器窗口,cookie就消失了。这种生命期为浏览器会话期的cookie被称为会话cookie。会话cookie一般不保存在硬盘上而是保存在内存里。
如果设置了过期时间,浏览器就会把cookie保存到硬盘上,关闭后再次打开浏览器,这些cookie依然有效直到超过设定的过期时间。
存储在硬盘上的cookie可以在不同的浏览器进程间共享,比如两个IE窗口。而对于保存在内存的cookie,不同的浏览器有不同的处理方式。

Cookie的读取

1.调用request.getCookies
要获取浏览器发送来的cookie,需要调用HttpServletRequest的getCookies方法,这个调用返回Cookie对象的数组,对应由HTTP请求中Cookie报头输入的值。
2.对数组进行循环,调用每个cookie的getName方法,直到找到感兴趣的cookie为止

1.2 利用Cookie自动登陆

不需要填写用户名和密码等信息,可以自动登录到系统。

登陆页面

login.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>

    <form action="index.jsp" method="post">

        name: <input type="text" name="name"/>

        <input type="submit" value="Submit"/>

    </form>

</body>
</html>

登陆会转向index.jsp

  • 若获取的请求参数 loginName不为空, 则打印出欢迎信息。把登录信息存储到 Cookie 中,并设置 Cookie 的最大时效为 30S
  • 从 Cookie 中读取用户信息,若存在则打印欢迎信息
  • 若既没有请求参数,也没有 Cookie,则重定向到 login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>

    <%
        //若可以获取到请求参数 name, 则打印出欢迎信息。把登录信息存储到 Cookie 中,并设置 Cookie 的最大时效为 30S
        String name = request.getParameter("name");
        if(name != null && !name.trim().equals("")){
            Cookie cookie = new Cookie("name", name);
            cookie.setMaxAge(30);
            response.addCookie(cookie);
        }else{
            //从 Cookie 中读取用户信息,若存在则打印欢迎信息
            Cookie [] cookies = request.getCookies();
            if(cookies != null && cookies.length > 0){
                for(Cookie cookie : cookies){
                    String cookieName = cookie.getName();
                    if("name".equals(cookieName)){
                        String val = cookie.getValue();
                        name = val;
                    }
                }
            }
        }

        if(name != null && !name.trim().equals("")){
            out.print("Hello: " + name);
        }else{
            //若既没有请求参数,也没有 Cookie,则重定向到 login.jsp
            response.sendRedirect("login.jsp");
        }

    %>

</body>
</html>

1.3 利用Cookie显示最近浏览的商品

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" import="java.util.*"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>

    <h4>Books Page</h4>

    <a href="book.jsp?book=JavaWeb">Java Web</a><br><br>
    <a href="book.jsp?book=Java">Java</a><br><br>
    <a href="book.jsp?book=Oracle">Oracle</a><br><br>
    <a href="book.jsp?book=Ajax">Ajax</a><br><br>
    <a href="book.jsp?book=JavaScript">JavaScript</a><br><br>
    <a href="book.jsp?book=Android">Android</a><br><br>
    <a href="book.jsp?book=Jbpm">Jbpm</a><br><br>
    <a href="book.jsp?book=Struts">Struts</a><br><br>
    <a href="book.jsp?book=Hibernate">Hibernate</a><br><br>
    <a href="book.jsp?book=Spring">Spring</a><br><br>

    <br><br>

    <%
        //显示最近浏览的 5 本书
        //获取所有的 Cookie
        Cookie [] cookies = request.getCookies();

        //从中筛选出 Book 的 Cookie:如果 cookieName 为 ATGUIGU_BOOK_ 开头的即符合条件
        //显示 cookieValue
        if(cookies != null && cookies.length > 0){
            for(Cookie c: cookies){
                String cookieName = c.getName();
                if(cookieName.startsWith("AIDATA_BOOK_")){
                    out.println(c.getValue());
                    out.print("<br>");
                }
            }
        }

    %>

</body>
</html>

显示最近浏览的 5 本书
获取所有的 Cookie
从中筛选出 Book 的 Cookie:如果 cookieName 为 AIDATA_BOOK_ 开头的即符合条件
显示 cookieValue

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" import="java.util.*"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>

    <h4>Book Detail Page</h4>

    Book: <%= request.getParameter("book") %>

    <br><br>

    <a href="books.jsp">Return</a>

    <%
        String book = request.getParameter("book");

        //把书的信息以 Cookie 方式传回给浏览器,删除一个 Cookie
        //1. 确定要被删除的 Cookie:
        //前提: AIDATA_BOOK_ 开头的 Cookie 数量大于或等于 5,
        Cookie [] cookies = request.getCookies();

        //保存所有的 AIDATA_BOOK_ 开头的 Cookie
        List<Cookie> bookCookies = new ArrayList<Cookie>();
        //用来保存和 books.jsp 传入的 book 匹配的那个 Cookie
        Cookie tempCookie = null;

        if(cookies != null && cookies.length > 0){
            for(Cookie c: cookies){
                String cookieName = c.getName();
                if(cookieName.startsWith("AIDATA_BOOK_")){
                    bookCookies.add(c);

                    if(c.getValue().equals(book)){
                        tempCookie = c;
                    }
                }
            }
        }

        //①. 且若从 books.jsp 页面传入的 book 不在 AIDATA_BOOK_ 的 Cookie 中则删除较早的那个 Cookie
        //( ATGUIGU_BOOK_  数组的第一个 Cbookie),
        if(bookCookies.size() >= 5 && tempCookie == null){
            tempCookie = bookCookies.get(0);
        }

        //②. 若在其中,则删除该 Cookie
        if(tempCookie != null){
            tempCookie.setMaxAge(0);
            response.addCookie(tempCookie);
        }

        //2. 把从 books.jsp 传入的 book 作为一个 Cookie 返回

        Cookie cookie = new Cookie("AIDATA_BOOK_" + book, book);
        response.addCookie(cookie);

    %>

</body>
</html>

把书的信息以 Cookie 方式传回给浏览器,删除一个 Cookie
确定要被删除的 Cookie: AIDATA_BOOK_ 开头的 Cookie 数量大于或等于 5,且若从 books.jsp 页面传入的 book 不在 ATGUIGU_BOOK_ 的 Cookie 中则删除较早的那个 Cookie( AIDATA_BOOK_ 数组的第一个 Cbookie),若在其中,则删除该 Cookie
把从 books.jsp 传入的 book 作为一个 Cookie 返回

1.4 设置Cookie作用路径

功能:
帮助网站实现提示客户端计算机上次访问网站的时间
实现原理:
将每一个会话作为一次访问过程,将每次会话的开始时间作为每次访问网站的时间,然后将这个时间以Cookie的形式存储到客户端的计算机中,客户端进行下次访问时通过该Cookie回传上次访问站点的时间值。
为了让Cookie信息在客户端浏览器或计算机关闭后仍然保持存在,Cookie的保存时间被设置为了一年。

二、Session

原文地址:https://www.cnblogs.com/aidata/p/12000005.html

时间: 2024-08-04 03:43:13

JavaWeb(六):会话与状态管理的相关文章

[原创]java WEB学习笔记28: 会话与状态管理Cookie 机制

1.会话与状态管理 1)背景 ① HTTP协议是一种无状态的协议,WEB服务器本身不能识别出哪些请求是同一个浏览器发出的 ,浏览器的每一次请求都是完全孤立的: ② 作为 web 服务器,必须能够采用一种机制来唯一地标识一个用户,同时记录该用户的状态: ③ 问题:怎么才能实现网上商店中的购物车呢:某个用户从网站的登录页面登入后,再进入购物页面购物时,负责处理购物请求的服务器程序必须知道处理上一次请求的程序所得到的用户信息. 2)会话和会话状态 ① WEB应用中的会话:指一个客户端浏览器与WEB服务

JavaWeb——使用会话维持状态2

在这次的例子里面,将完成一类似购物车的功能,在客户访问网站的时候,会选中自己将要购买的商品,而购物车将始终维持着商品的状态,会话将联系起选择第一个商品(第一个请求),选择其他商品(其他请求)以及付款等等操作. 1.在Web.xml中配置会话 <session-config> <session-timeout>30</session-timeout> <cookie-config> <http-only>true</http-only>

SERVLETJSP学习(六)—— 状态管理-cookie

1. 状态管理-Cookie 1.1. 状态管理 1.1.1. 为什么需要状态管理 Web应用程序使用HTTP协议作为传输数据的标准协议,而HTTP协议是无状态协议,即一次请求对应一次响应,响应结束后连接即断开,同一个用户的不同请求对于服务器端来讲并不会认为这两个请求有什么关联性,并不会以此区分不同的客户端.但实际情况中还是需要服务器端能够区分不同的客户端以及记录与客户端相关的一些数据,所以状态管理能够做到不同客户端的身份识别. 1.1.2. 什么是状态管理 将客户端与服务器之间多次交互当做一个

状态管理之cookie使用及其限制、session会话

# 1.什么是状态管理? 将浏览器与web服务器之间多次交互当作一个整体来处理,并且将多次交互所涉及的数据(即状态)保存下来.(cookie浏览器所涉及到的访问数据保存下来)# 2.如何进行状态管理? 方式一 将状态保存在浏览器端(Cookie). 方式二 将状态保存在服务器端(Session). # 3.Cookie## (1)什么是Cookie? 服务器临时存放在浏览器端的少量数据. ## (2)工作原理 当浏览器访问服务器时,服务器将少量数据以set-cookie消息头的形式发送给浏览器,

web应用程序的状态管理

一.Web应用程序状态形式1.表单隐藏字段2.cookie——把用户状态信息通过服务器发送到客户端浏览器中保存3.Session会话跟踪,服务器为客户端创建并维护的用于存放客户状态数据的session对象4.URL地址重写.(一)cookie 1:Cookie原理: 服务器在响应请求时将一些数据以“键-值”对的形式通过响应信息保存在客户端,当浏览器再次访问相同的应用时,会将原先的Cookie通过请求信息带到服务器端. Cookie cookie = new Cookie("cool",

HttpClient第三章 HTTP状态管理

原始的HTTP被设置成无状态的面向请求响应的协议,它并没有为基于跨几个逻辑相关的请求/响应交换的有状态会话提供所需的功能.但是随着HTTP协议越来越流行并且被应用,越来越多的系统开始用它作为原本并不是它的作用的功能,例如,电子商务传输应用,这样一来,对于状态管理的支持成为一个必要的功能. 那时网景公司作为一个web客户端和服务器端软件的领导开发者在他们的一个基于特殊的说明的产品里实现了对HTTP状态管理的支持,后来,网景通过发布一个知指导说明书试图标准化这一机制.这些努力促成了通过RFC标准的正

ASP.NET状态管理详解,让你明明白白

开发WinFrom的程序员可能不会在意维护应用程序的状态,因为WinFrom本身就在客户端运行,可以直接在内存中维护其应用程序状态.但ASP.NET应用程序在服务器端运行,客户端使用无状态的http协议对ASP.NET应用程序发出请求,ASP.NET应用程序响应用户请求,向客户端发送请求的HTML代码,服务器并不会维护任何客户端状态.考虑一个有成千上万并发用户的服务器,如果为每一个用户都维护状态的话会耗费非常多的资源. 由于使用无状态的http协议作为web应用程序的通信协议,当客户端每次请求页

httpClient HTTP状态管理

HTTP状态管理 原始的HTTP是被设计为无状态的,面向请求/响应的协议,没有特殊规定有状态的,贯穿一些逻辑相关的请求/响应交换的会话.由于HTTP协议变得越来越普及和受欢迎,越来越多的从前没有打算使用它的系统也开始为应用程序来使用它,比如作为电子商务应用程序的传输方式.因此,支持状态管理就变得非常必要了. 网景公司,一度成为Web客户端和服务器软件开发者的领导方向,在它们基于专有规范的产品中实现了对HTTP状态管理的支持.之后,网景公司试图通过发布规范草案来规范这种机制.它们的努力通过RFC标

JSP-JSP状态管理

http协议的无状态性 1.无状态是指,当浏览器发送请求给服务器的时候,服务器会响应.但当同一个浏览器再次发送请求时,服务器不会知道是刚才那个浏览器. 2.简单说,服务器[不会保存用户状态],不会记得客户端是否访问过,所以这就是无状态协议. jsp状态管理 保存用户状态的两大机制 1.Session 2.Cookie 什么是cookie? cookie:是web服务器保存在客户端的一系列文本信息. 典型应用之一:判断注册用户是否已经登录网站. 典型二:保存用户浏览记录. cookie的作用: 1