session和cookie内幕详解

cookie

Cookie 是服务器通知客户端保存键值对的一种技术。 客户端有了 Cookie 后,每次请求都发送给服务器。

注意:每个 Cookie 的大小不能超过 4kb。

创建cookie

//1.创建cookie
Cookie cookie1 = new Cookie("key1","value1");
//2.通知客户端保存cookie(通过响应头set-cookie通知客户端保存cookie)
resp.addCookie(cookie1);

服务器获取cookie

Cookie[] cookies = req.getCookies();
Cookie cookie = CookieUtils.findCookie("key", cookies);
public class CookieUtils {
    
    
    public static Cookie findCookie(String name , Cookie[] cookies){
    
    
        if (name == null || cookies == null || cookies.length == 0) {
    
    
            return null;
        }
        for (Cookie cookie : cookies) {
    
    
            if (name.equals(cookie.getName())) {
    
    
                return cookie;
            }
        }
        return null;
    }
}

修改cookie

方案一:

  • 先创建一个要修改的同名(指的就是 key)的 Cookie 对象
  • 在构造器,同时赋于新的 Cookie 值
  • 调用 response.addCookie( Cookie )
Cookie cookie = new Cookie("key1","newValue1");
response.addCookie(Cookie); 

方案二:

  • 先查找到需要修改的 Cookie 对象
  • 调用 setValue()方法赋于新的 Cookie 值
  • 调用 response.addCookie()通知客户端保存修改
Cookie cookie = CookieUtils.findCookie("key2", req.getCookies()); 
if (cookie != null) {
    
    
	cookie.setValue("newValue2");
	resp.addCookie(cookie);
}

Cookie 生命控制

Cookie 的生命控制指的是,管理 Cookie 什么时候被销毁(删除)。

  • setMaxAge()
    • 正数,表示在指定的秒数后过期(单位是秒)
    • 负数,表示浏览器一关,Cookie 就会被删除(默认值是-1)
    • 零,表示马上删除 Cookie
Cookie cookie = new Cookie("life3600", "life3600"); 
cookie.setMaxAge(60 * 60); // 设置Cookie 一小时之后被删除。无效 
resp.addCookie(cookie); 

cookie.setMaxAge(0); // 立即删除cookie

cookie.setMaxAge(-1); //浏览器一关,Cookie 就会被删除

Cookie 有效路径 Path 的设置

Cookie 的 path 属性可以有效的过滤哪些 Cookie 可以发送给服务器,哪些不发。 path 属性是通过请求的地址来进行有效的过滤。

假设:CookieA path=/工程路径,CookieB path=/工程路径/abc

则不同请求地址的不同发送情况如下:

  • http://ip:port/工程路径/a.html
    • CookieA 发送 ,CookieB 不发送
  • http://ip:port/工程路径/abc/a.html
    • CookieA 发送,CookieB 发送
Cookie cookie = new Cookie("path1", "path1"); 
// getContextPath() ===>>>> 得到工程路径 
cookie.setPath( req.getContextPath() + "/abc" ); //  /工程路径/abc 
resp.addCookie(cookie); 
resp.getWriter().write("创建了一个带有 Path 路径的 Cookie");

举例:用户登录后记住用户名:

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
    
    
    String username = req.getParameter("username");
    String password = req.getParameter("password");
    if (true) {
    
     //假设登陆成功
        Cookie nameCookie = new Cookie("username", username);
        resp.addCookie(nameCookie);
        nameCookie.setMaxAge(60 * 60 * 24 * 7);
        System.out.println("登陆成功");
    }

}

Session

Session 是一个接口(HttpSession)。

Session 是会话。它是用来维护一个客户端和服务器之间关联的一种技术。每个客户端都有自己的一个 Session 会话。Session 会话中,经常用来保存用户登录之后的信息


创建和获取 Session。

  • request.getSession()
    • 第一次调用是:创建 Session 会话
    • 之后调用是:获取前面创建好的 Session 会话对象。
  • isNew(); 判断到底是不是刚创建出来的(新的)
    • true 表示刚创建
    • false 表示获取之前创建
  • getId() ; 得到 Session 的会话 id 值
    • 每个会话都有一个身份证号。也就是 ID 值。而且这个 ID 是唯一的。

session存取域数据

req.getSession().setAttribute("key1", "value1");//A中利用session设置域数据

Object attribute = req.getSession().getAttribute("key1");//B中根据session的key获取域数据的值

Session生命周期控制

  • public void setMaxInactiveInterval(int interval) 设置 Session 的超时时间(以秒为单位),超过指定的时长,Session
    就会被销毁
    • 值为正数的时候,设定 Session 的超时时长。
    • 负数表示永不超时(极少使用)
  • public int getMaxInactiveInterval() 获取 Session 的超时时间
  • public void invalidate() 让当前 Session 会话马上超时无效

如果说,希望 web 工程默认的 Session 的超时时长为其他时长。可以在自己的 web.xml 配置文件中做以上相同的配置。就可以修改web 工程所有 Seession 的默认超时时长。

<session-config> 
    <session-timeout>20</session-timeout>
</session-config>

如果想只修改个别 Session 的超时时长。就可以使用上面的 API。setMaxInactiveInterval(int interval)来进行单独的设 置。

注意:

  • session超时指的是,客户端两次请求的最大间隔时长。
  • session 技术,底层其实是基于 Cookie 技术来实现的。
  • cookie设置在客户端,session设置在服务器端。

浏览器和 Session 之间关联的技术内幕

在这里插入图片描述
当客户端第一次访问服务器端时,本地无任何cookie信息,此时服务器会创建一个session和一个cookie,这个cookie对象存储的键值对的key是唯一标识用户的JSESSIONID,value就是对应的session值,服务器端会把这个session对象存储在本地内存中,同时将携带着session信息的cookie对象发送给客户端(响应头中),客户端收到这个cookie后会进行解析并且存储在本地。之后客户端每次访问服务器都会带着这个内部保存着JSESSIONID的cookie对象(请求头中),直到cookie失效(过期)或者session失效(过期或关闭浏览器),这也就是服务器端可以根据session可以区分不同用户的原因所在。

举例:用户登录和注销:

	protected void logout(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
//        1、销毁Session中用户登录的信息(或者销毁Session)
        req.getSession().invalidate();
//        2、重定向到首页(或登录页面)。
        resp.sendRedirect(req.getContextPath());
    }
    
    protected void login(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    

        //  1、获取请求的参数
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        // 调用 userService.login()登录处理业务
        User loginUser = userService.login(new User(null, username, password, null));
        // 如果等于null,说明登录 失败!
        if (loginUser == null) {
    
    
            // 把错误信息,和回显的表单项信息,保存到Request域中
            req.setAttribute("msg", "用户或密码错误!");
            req.setAttribute("username", username);
            //   跳回登录页面
            req.getRequestDispatcher("/pages/user/login.jsp").forward(req, resp);
        } else {
    
    
            // 登录 成功
            // 保存用户登录的信息到Session域中
            req.getSession().setAttribute("user", loginUser);
            //跳到成功页面login_success.html
            req.getRequestDispatcher("/pages/user/login_success.jsp").forward(req, resp);
        }

    }

JSON

JSON (JavaScript Object Notation) 是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成,是一种理想的数据交换格式。(数据交换指的是客户端和服务器之间业务数据的传递格式)

json 是由键值对组成,并且由花括号(大括号)包围。每个键由引号引起来,键和值之间使用冒号进行分隔, 多组键值对之间进行逗号进行分隔。

举例:javaBean 和 json 的互转:

@Test
public void test1(){
    
    
    User person = new User(1,"刘星星","123456","[email protected]");
    Gson gson = new Gson();
    String personJsonString = gson.toJson(person);
    System.out.println(personJsonString);
    //{"id":1,"userName":"刘星星","password":"123456","email":"[email protected]"}
    User person1 = gson.fromJson(personJsonString, User.class);
    //User{id=1, userName='刘星星', password='123456', email='[email protected]'}
    System.out.println(person1);
}

//核心步骤:
Gson gson = new Gson();
String s = gson.toJson(person);
User user = gson.fromJson(personJsonString, User.class);
//类似互转也可以应用在List、Map等中

猜你喜欢

转载自blog.csdn.net/qq_40585800/article/details/106628439
今日推荐