SessionCookie 学习笔记

Posted bgzyy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SessionCookie 学习笔记相关的知识,希望对你有一定的参考价值。

  在开始今天的博文之前首先为自己庆祝一下自己有了三个粉丝,也有了同僚的评论,说实话因为这个开心了好久!哈哈,好了在开始今天的正题之前,首先大家需要了解以下几点:

    a. HTTP 协议是无状态的协议,WEB 服务器本身不能识别出哪些请求是同一个浏览器发出的,浏览器的每一次请求都是孤立的;

    b. 作为服务器必须能够采用一种机制来唯一标识一个用户,同时记录该用户的状态;

    c. WEB 应用中的会话是指一个客户端浏览器与 WEB 服务器之间连续发生的一系列请求和响应过程;

    d. WEB 应用的会话状态是指 WEB 服务器与浏览器会话过程中产生的状态信息,借助会话状态 WEB 服务器能够把属于同一会话中的一系列的请求和响应过程关联起来;

    e. Cookie 机制采用的是在客户端保持 HTTP 状态信息的方案,在浏览器访问 WEB 服务器的某个资源时,由 WEB 服务器在 HTTP 响应消息头中附带传送给浏览器的一个小文本文件,一旦WEB 浏览器保存了某个 Cookie,那么他在以       后每次访问该 WEB 服务器时,都会在 HTTP 请求头中将这个 Cookie 回传给 WEB 服务器

1.  Cookie

  1). 实现原理:WEB 服务器通过在 HTTP 响应头消息中增加 Set-Cookie 响应头字段将 Cookie 消息发送给浏览器,浏览器则通过在 HTTP 请求消息中增加 Cookie 请求头字段将 Cookie 回传给 WEB 服务器

  2). 第一次访问浏览器不存在 Cookie,服务器给浏览器响应时给其加上 Cookie,第二次请求的时候便会自动加上 Cookie,服务器便会根据此 cookie 信息辨别用户状态,以弥补 HTTP 协议的无状态缺点  

  1.1 Cookie 应用实例之用户的自动登录

    a. 用户登录后会跳转到一个欢迎页面,一段时间之内我们再次访问欢迎页面时可以不用登录,但是过了 Cookie 的保质期我们访问欢迎页面的时候就需要去登录

    b. 首先我们写一个登录页面,然后提交请求到 servlet,在 servlet 中判断 cookie 中是否有值,若没有值可能是 cookie 失效,可能是第一次访问,然后将用户登录信息保存到 cookie 中;若有值则去判断该 cookie 中是否有匹配的 cookie,若有则显示欢迎页面,否则回到登录页面(登录页面中只有用户名,没有密码,在实际中我们对密码需要进行加密处理),演示如下:

    e. 代码如下(我们在 JSP 中模仿 Servlet,没有单独去新建 Servlet):

    login.jsp

 1 <%@ page contentType="text/html;charset=UTF-8" language="java" %>
 2 <html>
 3 <head>
 4     <title>Login</title>
 5 </head>
 6 <body>
 7 <form action="welcom.jsp" method="post">
 8     UserName: <input type="text" name="name"><br>
 9     <button type="submit">Submit</button>
10 </form>
11 </body>
12 </html>

  welcom.jsp

 1 <%--
 2   Created by IntelliJ IDEA.
 3   User: yin‘zhao
 4   Date: 2017/11/15
 5   Time: 9:30
 6   To change this template use File | Settings | File Templates.
 7 --%>
 8 <%@ page contentType="text/html;charset=UTF-8" language="java" %>
 9 <html>
10 <head>
11     <title>Welcom</title>
12 </head>
13 <body>
14 <h3>
15     <%
16         /*
17         * 获取用户名和cookie,如果用户名不为空(从登录页面而来)则打印欢迎消息
18         * 如果用户名为空但cookie 不为空,且cookie 的name 为所要求的同样打印欢迎消息
19         * 如果都为空则重定向到登录页面
20         * */
21 
22         String userName = request.getParameter("name");
23         if (userName != null) {
24             Cookie cookie1 = new Cookie("name", userName);
25             cookie1.setMaxAge(30);
26             response.addCookie(cookie1);
27         } else {
28 //            获取所有的 Cookie
29             Cookie[] cookies2 = request.getCookies();
30             if (cookies2 != null && cookies2.length > 0) {
31                 for (Cookie cookie : cookies2) {
32 //                    寻找相匹配的 Cookie
33                     if (cookie.getName().equals("name")) {
34 //                        使得 userName 为所匹配的 Cookie 的值
35                         userName = cookie.getValue();
36                     }
37                 }
38             }
39         }
40 
41         if (userName != "" && userName != null) {
42 //            打印欢迎消息
43             out.print("Hello" + userName);
44         } else {
45 //            如果用户名为空则重定向到登录页面
46             response.sendRedirect("login.jsp");
47         }
48     %>
49 </h3>
50 </body>
51 </html>

  1.2 显示最近浏览记录(只显示 5 条)

    a. 在显示页面显示出商品清单,点击商品后转到详情页面,然后再次返回到页面此商品将会显示到历史记录中

    b. 如果所浏览的是以前所浏览过的那么就需要将此商品更新到最新的记录中,即最后一个,演示如下

  代码如下(依旧使用 jsp 模仿 servlet)

 1 <%--
 2   Created by IntelliJ IDEA.
 3   User: yin‘zhao
 4   Date: 2017/11/15
 5   Time: 8:59
 6   To change this template use File | Settings | File Templates.
 7 --%>
 8 <%--
 9     从 Cookie 中获取书的信息并显示,如果 Cookie 的 name 是以 book 开始的就将其显示到页面
10 --%>
11 <%@ page contentType="text/html;charset=UTF-8" language="java" %>
12 <html>
13 <head>
14     <title>Cookie</title>
15 </head>
16 <body>
17 <a href="book.jsp?book=javaWeb">JavaWeb</a><br>
18 <a href="book.jsp?book=Java">Java</a><br>
19 <a href="book.jsp?book=Oracle">Oracle</a><br>
20 <a href="book.jsp?book=mysql">Mysql</a><br>
21 <a href="book.jsp?book=JDBC">JDBC</a><br>
22 <a href="book.jsp?book=C">C</a><br>
23 <a href="book.jsp?book=R">R</a><br>
24 <a href="book.jsp?book=Hibernate">Hibernate</a><br>
25 <a href="book.jsp?book=Ajax">Ajax</a><br>
26 <a href="book.jsp?book=Spring">Spring</a><br>
27 
28 <h2>
29     <%
30         Cookie[] cookies = request.getCookies();
31         for (Cookie cookie : cookies) {
32             if (cookie.getName().startsWith("book")) {
33                 out.print(cookie.getValue() + "<br>");
34             }
35         }
36     %>
37 </h2>
38 </body>
39 </html>
 1 <%@ page import="java.util.ArrayList" %>
 2 <%@ page import="java.util.List" %>
 3 <%--
 4     把书的信息以 Cookie 传回浏览器,如果以 book 开头的 cookie name 属性大于 5, 那么删除一个,如果新来的book
 5     已经存在,那么将其放到最后,如果不存在则删除第一个
 6 --%>
 7 <%@ page contentType="text/html;charset=UTF-8" language="java" %>
 8 <html>
 9 <head>
10     <title>Book</title>
11 </head>
12 <body>
13 <h3>
14     <%
15         String bookName = request.getParameter("book");
16 //        存储相同的 Cookie
17         Cookie tempCookie = null;
18 //        获得所有的 Cookie
19         Cookie[] cookies = request.getCookies();
20 //        存储Cookie 的 name 属性以 book 开头的并存储在 List 中
21         List<Cookie> cookieList = new ArrayList<Cookie>();
22 
23 //        遍历所有的 Cookie,将所有以 book 开头的存储在 List 中,并为 tempCookie 赋值
24         for (Cookie cookie1 : cookies) {
25             if (cookie1.getName().startsWith("book")) {
26                 cookieList.add(cookie1);
27                 if (cookie1.getValue().equals(bookName)) {
28                     tempCookie = cookie1;
29                 }
30             }
31         }
32 
33         System.out.println(tempCookie);
34 
35 //        如果 List 的 size 大于等于 5,且不存在相同的 Cookie 那么就删除第一个
36 //        要知道加入新的一个要么全部不相同且大于 5 删除第一个,要么存在相同的删除相同的
37 //        心得: 最后就是总删除一个,所以我们可以把删除的那个单独为其赋值
38         if (cookieList.size() > 5 && tempCookie == null) {
39             tempCookie = cookieList.get(0);
40         }
41         if (tempCookie != null) {
42             tempCookie.setMaxAge(0);
43 //            另一个不足为提的错误是没有将设置过的Cookie加入到Response中,因为服务器端设置了Cookie,客户端,
44 //            也就是浏览器是不知道的,所以对Cookie的所有修改都需要调用Response的addCookie方法给客户端响应,“存”回浏览器,这样,浏览器才会更改Cookie 集合
45             response.addCookie(tempCookie);
46         }
47 
48 //        获取调用 Servlet 的 Path, 但 JSP 底层就是一个 Servlet,所以会打印文件名
49 //        out.print(request.getServletPath());
50 //        将新传入的 cookie 返回
51         Cookie cookie = new Cookie("book" + bookName, bookName);
52         response.addCookie(cookie);
53     %>
54 </h3>
55 <h3><%=bookName%>
56 </h3>
57 <a href="index.jsp">Return...</a>
58 </body>
59 </html>

 

  以上便是我所对 cookie 的理解和自己练习的小应用,接下来我们开始讲解 session

2. session

   1).  Session 在 WEB 开发环境下的语义是指一类用来在客户端与服务器端之间保持状态的解决方法,有时候 Session 也用来指这中解决方案的存储结构

   2). 如果浏览器发一个 session 并没有带任何标识,服务器便会新建一个 session 对象,服务器返回响应的时候会以 cookie的方式返回标识头(JSessionId),下一次请求 cookie 会把这个标识 id 带回去,就会找到指定的 session,只要浏览器不关就会一直在 cookie存取数据

   3). Session 通过 sessionId 来区分不同的客户,session以cookie 或 URL 重写为基

   4). 础在程序中可以设置 cookie(JSESSIONID)的持久化,保证重启浏览器的不会重新发送

   5). HttpSession 的生命周期之创建 Session

            a. 浏览器访问服务端的任何一个 JSP,服务器不一定会立即创建一个 HttpSession 对象

         b. 若当前 JSP 是浏览器访问当前 WEB 资源的第一个资源且 JSP 的 page 指令的 session 设为 false,那么服务器就不会为 JSP 创建一个 HttpSession 对象(Page 指令的 session 属性为 false 是指 JSP 页面的隐含变量不可用,但可以通过显示的方法去创建。)

         c. 若当前 JSP 不是客户端访问的第一个,且其他页面已经创建了一个 HttpSession’ 对象,则服务器也不会为当前 JSP 页面创建一个 HttpSession 对象, 而会把和当前页面会话关联的那个 HttpSession 对象返回

         d. 对于 Servlet 若是第一个访问的资源,则只有调用了 request.getSession 或 request。getSession(true) 才会创建一个对象

  6). HttpSession 的生命周期之销毁 session

    a. 超出 HttpSession 的过期时间,调用  session.setMaxInactiveInterval(5)  设置失效时间,单位为秒

    b. 服务器调用  sesion.invalidate()  方法,

    c. 服务器卸载了当前 WEB 应用

  7). Servlet 中如何获取 HttpSession 对象

         a.  request.getsession(boolean)   boolean 为false ,表示若没有和当前JSP 页面关联的 HttpSession则返回 null,若有则返回对象;为 true 表示一定返回,若没有关联页面则服务器创建一个,此时的 true 可省略

   8). Session 应用案例之购物车

    a. 用户选择所要购买的商品,并填写订单信息后在购买页面显示用户所要购买的物品信息和用户信息(由于是多个请求跨页面,所以我们不能将信息存到 request 中)

    b. 代码如下(以下是我自己所写的代码,有点烦琐,代码注释中有自己写代码过程中所犯的错误和更好的解决方案,我这里就不贴出留给有兴趣的自己去实践):

index.jsp(由于此案例并不是一个请求所以我们再次利用反射使得所有请求利用一个 Servlet 和之前所用到的一样)