【JavaWeb】一文搞定JavaWeb之会话技术 Cookie&Session

JavaWeb之会话技术Cookie&Session

  • 一、会话技术简介
    • 1.什么是会话
    • 2.存储客户端的状态
    • 3.会话技术
  • 二、Cookie技术
    • 1.服务器向客户端发送一个Cookie
      • (1)创建Cookie
      • (2)设置Cookie在客户端的持久化时间
      • (3)设置cookie的携带路径
      • (4)向客户端发送cookie(以响应头的形式)
      • (5)删除cookie
    • 2.服务器获取客户端携带的Cookie
    • 3.案例:使用Cookie实现用户上次登录时间的显示
  • 三、Session技术
    • 1.获取Session对象
    • 2.向Session中存储数据(域对象)
    • 3.Session对象的声明周期(*)
    • 4.Session补充

一、会话技术简介

1.什么是会话

  • 指一个客户端(浏览器)与Web服务器之间连续发生的一系列请求和响应过程。
  • 例如,从打开一个浏览器访问某个站点,到关闭这个浏览器的整个过程,称为一次会话。

2.存储客户端的状态

    • Http协议是无状态的,也就是说每个客户访问服务器端资源时,服务器并不知道该客户是谁,所以需要会话技术识别客户端的状态。

3.会话技术

  • Cookie:数据存储在客户端本地,减少服务器端的存储压力,安全性不好,客户端可以清除cookie。
  • Session:将数据存储到服务器端,安全性相对好,增加服务器的压力。

二、Cookie技术

1.服务器向客户端发送一个Cookie

(1)创建Cookie

//格式
Cookie cookie = new Cookie(String cookieName,String cookieValue);
//示例:
Cookie cookie = new Cookie("username","zhangsan");
  • 该cookie会以响应头的形式发送给客户端。
  • 注意:Cookie不能存储中文,也不能存储对象,只能存非中文字符串。

(2)设置Cookie在客户端的持久化时间

//格式:
cookie.setMaxAge(int seconds);//时间为秒
//示例:
cookie.setMaxAge(60*10);
//设置cookie信息在浏览器的磁盘文件中存储10分钟,过期浏览器自动删除该cookie信息。
  • 注意:如果不设置持久化时间,cookie会存储在浏览器的内存中,浏览器关闭后cookie销毁(会话级别的cookie),如果设置持久化时间,cookie的信息会被持久化到浏览器的硬盘文件中。

(3)设置cookie的携带路径

//格式:
cookie.setPath(String path);
//示例:
cookie.setPath("/项目名称/cookieServlet");//代表访问该项目中的cookieServlet时才携带这个cookie信息
cookie.setPath("/项目名称");//访问该项目下的任何资源时都携带这个cookie信息
cookie.setPath("/");//访问服务器下的所有的资源都携带这个cookie信息
  • 注意:如果不设置携带路径,那么该cookie信息会在访问产生该cookie的web资源所在的路径时都携带cookie信息(同一级别目录下的资源)。

(4)向客户端发送cookie(以响应头的形式)

//格式:
response.addCookie(Cookie cookie);

(5)删除cookie

  • 如果想删除客户端的已经存储的cookie信息,那么就使用同名同路径的持久化时间为0的cookie进行覆盖即可。
//格式:
cookie.setMaxAge(0);
cookie.setPath("与要删除cookie的路径相同");

2.服务器获取客户端携带的Cookie

//格式:
//获取客户端携带的cookie的数据
Cookie[] cookies = request.getCookies();
//通过cookie名称获得想要的cookie
if(cookies!=null){
    for(Cookie cookie : cookies){
    	//获取cookie的名称
    	String cookieName = cookie.getName();
    	if(cookieName.equals("name")){
        	//获得该cookie的值
        	String cookieValue = cookie.getValue();
        	System.out.println(cookieValue);
    	}
	}
}

3.案例:使用Cookie实现用户上次登录时间的显示

  • 简单jsp页面(main.jsp)
<%--
  Created by IntelliJ IDEA.
  User: lenovo
  Date: 2020-03-04
  Time: 16:17
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>主页</title>
</head>
<body>
//使用request获取标记lastTime,并结合三元运算方式显示到页面上
<%=request.getAttribute("lastTime")==null?"":"您上次登录时间为:"+request.getAttribute("lastTime")%>
</body>
</html>

  • 简单的Servlet页面
package cn.mrzhang.app.cookie;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

@WebServlet("/cookie")
public class CookieServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request,response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        //获取上次访问时间
        //1.获取request域中的cookie,存放在cookie数组中
        Cookie[] cookies = request.getCookies();
        //2.判断cookie数组是否为空
        if (cookies!=null){
        	//3.遍历cookie数组
            for (Cookie c : cookies) {
                String name = c.getName();
                //4.取出上次访问时间
                if ("lastTime".equals(name)){
                    String time = c.getValue();
                    //5.将时间存放到标记中去
                    request.setAttribute("lastTime",time);
                }
            }
        }

        //记录本次访问时间
        //1.创建date对象
        Date date = new Date();
        //2.格式化date
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd--hh:mm:ss");
        String fDate = sdf.format(date);
        System.out.println(fDate);
        //3.创建cookie对象,并且将时间放入
        Cookie cookie = new Cookie("lastTime",fDate);
        //4.设置cookie在客户端的持久化时间
        cookie.setMaxAge(60*10);
        //5.设置cookie的携带路径
        cookie.setPath("/cookie");
        //6.以响应头的方式向客户端发送cookie
        response.addCookie(cookie);

        //7.跳转页面
        request.getRequestDispatcher("main.jsp").forward(request,response);
    }
}

三、Session技术

  • Session技术是将数据存储在服务器端的技术,会为每个客户端都创建一块内存空间存储客户的数据,但客户端需要每次都携带一个标识ID去服务器中寻找属于自己的内存空间。
  • Session技术的实现是基于Cookie的,Session需要借助Cookie存储客户唯一性标识JSESSIONID 。
  • 发送编号和根据编号去寻找Session区域位置,这些操作是客户端和服务器自动完成,不需要手动编码。
  • Session是一个域对象,范围是一次会话当中。

1.获取Session对象

  • getSession();
    • 创建属于该客户端(会话)的私有的session区域
    • request.getSession()方法会判断该客户端是否在服务器端已经存在session。
    • 如果不存在session,那么就会创建一个新的session对象。
    • 如果存在session,那么就获得已经存在的该session对象返回。
    • 实质就是根据JSESSIONID判断该客户端是否在服务器上已经存在session。
//格式:
//创建属于该客户端(会话)的私有的session区域
HttpSession session = request.getSession(); 
//获取该session对象的编号id,也就是JSESSIONID
String id = session.getId();

2.向Session中存储数据(域对象)

  • setAttribute(String name ,Object obj);
  • getAttribute(String name);
  • removeAttribute(String name);
//向session中存储数据
HttpSession session = request.getSession();
session.setAttribute("name","zhangsan");
//从session中获取存储的数据
HttpSession session = request.getSession();
String attribute = (String)session.getAttribute("name");

3.Session对象的声明周期(*)

  • 创建:
    • 第一次执行request.getSession()时创建。
    • 客户端访问服务器端,服务器端在执行到request.getSession()时,它会看一下有没有属于该客户端的session区域
  • 销毁:
    1. 服务器关闭时销毁(非正常关闭)。
    2. Session过期(默认为30分钟)
      - 可以在项目的web.xml中配置。
      - 时间的起算点:从不操作服务器的资源时开始计时。
      <session-config>
          <!-- session默认30分钟过期 -->
      	<session-timeout>30</session-timeout>
      </session-config>
      
    3. 手动销毁:session.invalidate();
  • 作用范围:默认在一次会话中,一次会话中任何资源共用一个session对象。

4.Session补充

  • 浏览器关闭,session就销毁了吗?
    • 不对,session销毁只有三种方式,服务器关闭,session过期,手动销毁。
  • JSESSIONID持久化
    • 假如存在两个Servlet类,在Servlet1中,将某个数据存入session,在Servlet2中,可以将session中的数据取出,但是如果关闭浏览器,再打开,直接到Servlet2中取session数据,数据的值为空。
    • 原因:
      • 这是因为存JSESSIONID的cookie是会话级别的,在浏览器关闭后,cookie销毁了,重新打开浏览器,去Servlet2中取session中的数据时,此session的JSESSIONID与存入数据的session的JSESSIONID不同,所以此session没有这个数据,所以会为空值。
    • 解决方法:将存JSESSIONID的cookie从会话级别转变为持久级别。
    • 手动创建一个存储JSESSIONID的cookie,为该cookie设置持久化时间。
    Cookie cookie = new Cookie("JSESSIONID",id);
    cookie.setPath("/项目名称");
    //设置持久化时间为10分钟
    cookie.setMaxAge(60*10);
    //将cookie发送给客户端
    response.addCookie(cookie);
    

你可能感兴趣的:(java,cookie,session,servlet)