狂神Java Web (六)Cookie & Session

Cookie & Session

会话:用户打开浏览器,点击很多链接,访问多个web资源,关闭浏览器,该过程可以称为会话。

有状态会话:一个网站,怎么证明你来过?
客户端 服务端

  1. 服务端给客户端一个信件,客户端下次访问服务端带上信件就可以了; cookie
  2. 服务器登记你来过了,下次来的时候匹配你; session

保存会话的两种技术

  • cookie
    • 客户端技术(响应,请求)
  • session
    • 服务器技术,可以保存用户的会话信息。可以把信息或数据放在Session中。

应用场景:自动登录

  1. 从请求中拿到cookie信息
  2. 服务器响应给客户端cookie
Cookie[] cookies = req.getCookies(); 	// 获得Cookie
cookie.getName();						// 获得Cookie中的键key
cookie.getValue();						// 获得Cookie中的值value
new Cookie("lastLoginTime", System.currentTimeMillis() + "");	// 新建一个Cookie
cookie.setMaxAge(24 * 60 * 60);			// 设置Cookie的有效期
resp.addCookie(cookie);					// 响应给客户端一个Cookie

Cookie:一般保存在本地的用户目录下, appdata;

保存上次登录时间的例子:

package com.maple.servlet;

import javax.servlet.ServletException;
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.io.PrintWriter;
import java.util.Date;

/**
 * 保存用户上一次访问的时间
 *
 * @author maple_w
 * Created on 21/07/28 028 19:59
 */
public class CookieServlet01 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");
        resp.setContentType("text/html;charset=utf-8");

        PrintWriter out = resp.getWriter();

        // Cookie, 服务器端从客户端获取
        Cookie[] cookies = req.getCookies();

        // 判断Cookie是否存在
        if (cookies != null) {
            out.write("上次访问的时间:");
            for (Cookie cookie : cookies) {
                String name = cookie.getName();
                String value = cookie.getValue();
                if (name.equals("lastLoginTime")) {
                    long l = Long.parseLong(value);
                    Date date = new Date(l);
                    out.write(date.toLocaleString());
                }
            }
        } else {
            out.write("首次访问");
        }

        // 服务器给客户端响应一个cookie
        Cookie cookie = new Cookie("lastLoginTime", System.currentTimeMillis() + "");

        // 设置cookie有效期为1天
        cookie.setMaxAge(24 * 60 * 60);

        resp.addCookie(cookie);

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

一个网站的Cookie是否存在上限?

  • 一个Cookie只能保存一个信息;
  • 一个web站点可以给浏览器发送多个cookie,最多存放20个;
  • 300个Cookie,浏览器上限;
  • Cookie大小有限制,4kb;

删除Cookie:

  • 不设置有效期,关闭浏览器,自动失效;
  • 设置有效期为0;(手动删除)

编码解码:

URLEncoder.encode("狂神", "utf-8")
URLDecoder.decode(cookie.getValue(), "utf-8"))

如果要读取中文Cookie,后台显示中文正常也不行,如果要浏览器显示正常,还需要添加:

	// 添加这个才能有效让页面显示中文不乱码
	resp.setContentType("text/html;charset=utf-8");

读取中文的小例子:

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

		req.setCharacterEncoding("utf-8");
		resp.setCharacterEncoding("utf-8");
		// 添加这个才能有效让页面显示中文不乱码
		resp.setContentType("text/html;charset=utf-8");

		PrintWriter out = resp.getWriter();

		Cookie[] cookies = req.getCookies();
		if (cookies != null) {
			for (Cookie cookie : cookies) {
				out.write(cookie.getName());
				out.write(URLDecoder.decode(cookie.getValue(), "utf-8"));
				System.out.println(cookie.getName());
				System.out.println(URLDecoder.decode(cookie.getValue(), "utf-8"));
			}
		}

		Cookie cookie = new Cookie("name", URLEncoder.encode("狂神", "utf-8"));
		resp.addCookie(cookie);
	}

Session (重点)

什么是session:

  • 服务器会给每个用户(浏览器)创建一个Session对象。
  • 每个Session独占一个浏览器,只要浏览器没有关闭,这个Session就存在。
  • 用户登录后,整个网站都可以访问。--> 保存用户信息、保存购物车信息等

Session和Cookie的区别:

  • Cookie把用户的数据写给用户的浏览器,浏览器保存;(可以保存多个)
  • Session把用户的数据写到用户独占的Session中,服务器端保存;(保存重要信息,减少服务器资源的浪费)
  • Session对象由服务器创建,

使用场景:

  • 保存一个登录用户的信息;
  • 购物车信息;
  • 在整个网站中经常会使用的数据,将其保存在session中;

使用session:
往Session中写信息:

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 解决乱码问题
        req.setCharacterEncoding("UTF-8");
        resp.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html;charset=utf-8");

        // 得到Session
        HttpSession session = req.getSession();

        // 给Session中存东西
        // session.setAttribute("name", "狂神");
        session.setAttribute("name", new Person("狂神", 33));

        // 获取Session的ID
        String id = session.getId();
        // 判断是否是新的Session
        if (session.isNew()) {
            resp.getWriter().write("session 创建成功, ID: " + id);
        } else {
            resp.getWriter().write("session 已经在服务器中存在了, ID: " + id);
        }

        // 猜想Session做了什么事情:
        // Cookie cookie = new Cookie("JSESSIONID",id);
        // resp.addCookie(cookie);

    }

从Session中读取信息:

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 解决乱码问题
        req.setCharacterEncoding("UTF-8");
        resp.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html;charset=utf-8");

        // 得到Session
        HttpSession session = req.getSession();

        // String name = (String) session.getAttribute("name");
        Person person = (Person) session.getAttribute("name");
        System.out.println(person);

    }

清除Session:

@Override  
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {  
 HttpSession session = req.getSession();  
 session.removeAttribute("name");  
 // 手动注销session,但因为浏览器在访问,会立即生成一个新的session  
 session.invalidate();  
}

或是在web.xml中设置默认失效时间:

    <!-- 设置session默认失效时间 -->
    <session-config>
        <!-- 15分钟后session自动失效,分钟为单位 -->
        <session-timeout>1</session-timeout>
    </session-config>

image

ServletContext (ApplicationContext)是在Session之上更高级的一个概念,可以存储多个不同用户的共享信息,如用户统计等。

posted @ 2021-07-28 21:47  Maple_w  阅读(114)  评论(0编辑  收藏  举报