JavaWeb-Cookie和Session

Cookie

Cookie是servlet发送到Web浏览器的少量信息,该信息由浏览器保存,然后发送回服务器。一般情况下,Cookie是以键值对进行表示的(key-value),Cookie的值可以唯一地标识客户端,因此Cookie常用于会话管理。servlet通过使用HttpServletResponse#addCookie方法将cookie发送到浏览器,该方法将字段添加到http响应头,以便一次一次地将cookie发送到浏览器,每个Cookie的大小限定为4kb。

创建Cookie

客户端没有Cookie        ->        服务器创建Cookie        ->        通知客户端保存Cookie        ->        通过响应头Set-Cookie通知客户端保存Cookie(Set-Cookie:key=value)        ->客户端收到响应后发现set-cookie响应头,查看有没有Cookie,如果没有就创建如果有就修改。

package com.pero.servlet.cookie_session;

import jakarta.servlet.*;
import jakarta.servlet.http.*;

import java.io.IOException;
import java.lang.reflect.Method;

public abstract class BaseServlet extends HttpServlet {

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

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

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

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

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        String action = request.getParameter("action");
        try {
            Method method = this.getClass().getDeclaredMethod(action, HttpServletRequest.class, HttpServletResponse.class);
            method.invoke(this,request,response);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
package com.pero.servlet.cookie_session;

import jakarta.servlet.*;
import jakarta.servlet.http.*;

import java.io.IOException;

public class CookieServlet extends BaseServlet {

    protected void createCookie(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //创建Cookie
        Cookie cookie = new Cookie("key","value");
        //通知客户端保存
        response.addCookie(cookie);
        response.getWriter().write("Cookie创建成功");
    }
}
<!DOCTYPE html>
<html lang="en">
<head>
  <meta http-equiv="pragma" content="no-cache" />
  <meta http-equiv="cache-control" content="no-cache" />
  <meta http-equiv="Expires" content="0" />
  <meta http-equiv="content-type" content="text/html;charset=UTF-8">
    <title>Cookie</title>
  <base href="http://localhost:8080/cookie_session/">
  <style type="text/css">
    ul li{
      list-style: none;
    }
  </style>
</head>
<body>
  <iframe name="target" width="500" height="500" style="..."></iframe>
  <div style="...">
    <ul>
      <li><a href="cookieServlet?action=createCookie" target="target">Cookie的创建</a></li>
      <li><a href="cookieServlet?action=getCookie" target="target">Cookie的获取</a></li>
      <li><a href="cookieServlet?action=updateCookie" target="target">Cookie值的修改</a></li>
      <li>Cookie的存活周期</li>
      <li>
        <ul>
          <li><a href="cookieServlet?action=defaultLifeCookie" target="target">Cookie的默认存活时间(会话)</a></li>
          <li><a href="cookieServlet?action=deleteNowCookie" target="target">Cookie立即删除</a></li>
          <li><a href="cookieServlet?action=life5Cookie" target="target">Cookie存活5秒</a></li>
        </ul>
      </li>
      <li><a href="cookieServlet?action=pathCookie" target="target">Cookie的路径设置</a></li>
      <li><a href="" target="target">Cookie的用户登录练习</a></li>
    </ul>
  </div>
</body>
</html>

服务器获取Cookie

客户端有了Cookie的值        ->        通过请求头:Cookie:key=value 把Cookie信息发送给服务器        ->        服务器获取客户端发送过来的Cookie只需要一行代码{request.getCookies():返回Cookie[]数组}

package com.pero.servlet.cookie_session;

import com.pero.servlet.util.CookieUtil;
import jakarta.servlet.*;
import jakarta.servlet.http.*;

import java.io.IOException;

public class CookieServlet extends BaseServlet {

    protected void getCookie(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Cookie[] cookies = request.getCookies();

        for (Cookie cookie : cookies) {
            //getName()获取Cookie的Key值,getValue()方法获取Cookie的value值
            response.getWriter().write("Cookie{" + cookie.getName() + ":" + cookie.getValue() + "} <br/>");
        }
        Cookie iWantCookie = CookieUtil.findCookie("key",cookies);
        //如果不等于null意味着找到了Cookie
        if (iWantCookie != null){
            response.getWriter().write("找到了Cookie");
        }
    }

    ...
}
package com.pero.servlet.util;

import jakarta.servlet.http.Cookie;

public class CookieUtil {
    /**
     * 查找指定名称的Cookie对象
     * @param name
     * @param cookies
     * @return
     */
    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值的修改

package com.pero.servlet.cookie_session;

import com.pero.servlet.util.CookieUtil;
import jakarta.servlet.*;
import jakarta.servlet.http.*;

import java.io.IOException;

public class CookieServlet extends BaseServlet {

    protected void updateCookie(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //方法一:
        //创建需要修改的同名Cookie对象
        //在构造器中同时赋予新的Cookie值
//        Cookie cookie = new Cookie("key","newValue");
        //调用response.addCookie(Cookie)
//        response.addCookie(cookie);
//        response.getWriter().write("key的Cookie的值已经修改");

        //方法二
        //查找需要修改的Cookie对象
        Cookie cookie = CookieUtil.findCookie("key",request.getCookies());
        //调用setValue()方法付于心的Cookie值
        if (cookie != null){
            cookie.setValue("NewCookie");
        }
        //调用response.addCookie(cookie)通知客户端保存修改
        response.addCookie(cookie);
    }
    ...
}

Cookie的生命控制

Cookie的生命控制指的是如何管理Cookie什么时候被销毁(删除)。setMaxAge();整数表示在指定秒数后过期,负数表示浏览器一关Cookie就会被删除(程序默认),0表示立刻删除Cookie。

package com.pero.servlet.cookie_session;

import com.pero.servlet.util.CookieUtil;
import jakarta.servlet.*;
import jakarta.servlet.http.*;

import java.io.IOException;

public class CookieServlet extends BaseServlet {

    protected void life5Cookie(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Cookie cookie = new Cookie("life5","life5");
        cookie.setMaxAge(5);    //设置Cookie5秒后删除
        response.addCookie(cookie);
        response.getWriter().write("创建了5秒钟的Cookie");
    }
    protected void deleteNowCookie(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //查找需要删除的Cookie
        Cookie cookie = CookieUtil.findCookie("key",request.getCookies());
        if (cookie != null){
            //设置cookie.setMaxAge(0);立刻销毁Cookie
            cookie.setMaxAge(0);
            //response.addCookie();浏览器保存
            response.addCookie(cookie);
            response.getWriter().write("key的Cookie已经被删除");
        }
    }
    protected void defaultLifeCookie(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Cookie cookie = new Cookie("defaultLife","defaultLife");
        cookie.setMaxAge(-1);   //设置存活时间为浏览器退出后Cookie被销毁
        response.addCookie(cookie);
    }
    ...
}

Cookie有效路径Path的设置

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

package com.pero.servlet.cookie_session;

import com.pero.servlet.util.CookieUtil;
import jakarta.servlet.*;
import jakarta.servlet.http.*;

import java.io.IOException;

public class CookieServlet extends BaseServlet {

    protected void pathCookie(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Cookie cookie = new Cookie("path","path");
        //getContextPath()得到工程路径
        cookie.setPath(request.getContextPath() + "/file");
        response.addCookie(cookie);
        response.getWriter().write("创建了一个带有Path路径的Cookie");
    }
    ...
}

Cookie练习免用户名登陆

第一次登录时:客户端(浏览器)第一次访问,服务器返回给客户端登陆页面,填写用户名和密码后提交给服务器,服务器获取用户名和密码,判断用户名和密码是否正确,正确允许登录,错误不允许登录,把用户名保存为Cookie发送给客户端,浏览器有了用户名和Cookie信息;

第二次登陆时:客户端(浏览器)第二次访问服务器会把Cookie信息发给服务器,服务器返回给客户端带用户名的登录界面。

package com.pero.servlet.cookie_session;

import jakarta.servlet.*;
import jakarta.servlet.http.*;

import java.io.IOException;

public class LoginServlet extends HttpServlet {
    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        if ("root".equals(username) && "root".equals(password)){
            //登陆成功
            Cookie cookie = new Cookie("username", username);
            cookie.setMaxAge(60*60*24*7);   //cookie一周内有效
            response.addCookie(cookie);
            System.out.println("登陆成功");
        }else {
            System.out.println("登陆失败");
        }
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }
}
<%--
  Created by IntelliJ IDEA.
  User: Administrator
  Date: 2023/3/16
  Time: 18:35
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <form action="http://localhost:8080/cookie_session/loginServlet" method="get">
        用户名:<input type="text" name="username" value="${cookie.username.value}"><br>
        密  码:<input type="password" name="password"><br>
        <input type="submit" value="登录">
    </form>
</body>
</html>

Session

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

创建Session和获取

request.getSession():第一次调用是创建Session会话,之后都是调用,获取前面创建好的Session会话对象;

isNew():判断是不是新创建出来的Session,true表示新创建,false表示获取之前创建的;

getId():得到Session会话的id值,每一个会话都有一个id值,这个id值是唯一的。

package com.pero.servlet.cookie_session;

import jakarta.servlet.*;
import jakarta.servlet.http.*;

import java.io.IOException;

public class SessionServlet extends BaseServlet {
    protected void createOrGetSession(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //创建和获取Session会话对象
        HttpSession session = request.getSession();
        //判断当前Session会话是否是新创建出来的
        boolean isNew = session.isNew();
        //获取Session会话的唯一标识
        String id = session.getId();

        response.getWriter().write("得到的Session的ID:" + id + " <br/>");
        response.getWriter().write("Session是否为新创建的:" + isNew + " <br/>");
    }

}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta http-equiv="pragma" content="no-cache"/>
    <meta http-equiv="cache-control" content="no-cache"/>
    <meta http-equiv="Expires" content="0"/>
    <meta http-equiv="content-type" content="text/html;charset=UTF-8">
    <title>Session</title>
    <base href="http://localhost:8080/cookie_session/">
    <style type="text/css">
        ul li {
            list-style: none;
        }
    </style>
</head>
<body>
<iframe name="target" width="500" height="500" style="..."></iframe>
<div style="...">
    <ul>
        <li><a href="sessionServlet?action=createOrGetSession" target="target">Session的创建和获取</a></li>
        <li><a href="" target="target">Session域数据的存储</a></li>
        <li><a href="" target="target">Session域数据的获取</a></li>
        <li>Session的存活周期</li>
        <li>
            <ul>
                <li><a href="" target="target">Session默认超时配置</a></li>
                <li><a href="" target="target">Session5秒超时销毁</a></li>
                <li><a href="" target="target">Session立刻销毁</a></li>
            </ul>
        </li>
        <li><a href="" target="target">浏览器和Session绑定的原理</a></li>
    </ul>
</div>
</body>
</html>

Session域中数据的存取

package com.pero.servlet.cookie_session;

import jakarta.servlet.*;
import jakarta.servlet.http.*;

import java.io.IOException;

public class SessionServlet extends BaseServlet {

    protected void getAttributeSession(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        HttpSession session = request.getSession();
        Object attribute = session.getAttribute("key");
        response.getWriter().write("从Session中获取key的值为:" + attribute);
    }

    protected void setAttributeSession(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        HttpSession session = request.getSession();
        session.setAttribute("key","value");
        response.getWriter().write("已经向Session中存储值");

    }

    ...
}

Session生命周期

Session超时是指客户端两次请求的最大间隔时间。

public void setMaxInactiveInterval(int interval):设置Session超时时间(以秒为单位),超过指定时长Session会被销毁,值为正数的时候,设定Session的超市时长,值为负数的时候,Session永不超时;

public void invalidate():让Session会话立刻超时无效;

public int getMaxInactiveInterval():获取Session的超时时间;

Session的默认超时时长为:Session的默认超时时长为1800秒。

package com.pero.servlet.cookie_session;

import jakarta.servlet.*;
import jakarta.servlet.http.*;

import java.io.IOException;

public class SessionServlet extends BaseServlet {

    protected void defaultLife(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        HttpSession session = request.getSession();
        int maxInactiveInterval = session.getMaxInactiveInterval();
        response.getWriter().write("Session的默认超时时长为" + maxInactiveInterval + "秒");
    }
    ...
}

 如果调整web工程的超时时长,可以在web.xml中进行配置。

<!-- 表示当前web工程创建出来的所有Session默认是20分钟超时时长 -->
    <session-config>
        <session-timeout>10</session-timeout>
    </session-config>

也可以通过setMaxInactiveInterval(int interval)设置Session超时时间

package com.pero.servlet.cookie_session;

import jakarta.servlet.*;
import jakarta.servlet.http.*;

import java.io.IOException;

public class SessionServlet extends BaseServlet {

    protected void life5Session(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        HttpSession session = request.getSession();
        //设置当前Session5秒后超时
        session.setMaxInactiveInterval(5);
        response.getWriter().write("当前Session已经设置为5秒后超时");
    }
    ...
}

设置Session立刻超时

package com.pero.servlet.cookie_session;

import jakarta.servlet.*;
import jakarta.servlet.http.*;

import java.io.IOException;

public class SessionServlet extends BaseServlet {

    protected void shutDownSession(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        HttpSession session = request.getSession();
        //设置当前Session立刻超时
        session.invalidate();
        response.getWriter().write("当前Session立刻超时关闭");
    }
    ...
}

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

Session技术底层是基于Cookie技术实现的。

客户端(浏览器)服务器服务器内存
没有Cookie信息

发送请求

request.getSession()

创建会话对象

Session1

Session2

Session3

Session4

Session5

Session6

Session7

Session8

保存Cookie信息

通过响应把新创建的Session的id值返回给客户端

JSESSIONID的值

服务器每次创建Session会话对象的时候都会创建一个Cookie对象。这个Cookie对象的key是JSESSIONID的值,是新创建出来的SessionID的值。
有Cookie信息

有了Cookie信息之后,每次请求都会把Session的ID以Cookie的形式发送给服务器

request.getSession()

通过Cookie中的id值找到创建好的Session对象,并返回

删除Cookie
没有Cookie信息

发送请求

request.getSession()

创建会话对象

保存Cookie信息

通过响应把新创建的Session的id值返回给客户端

JSESSIONID的值

服务器每次创建Session会话对象的时候都会创建一个Cookie对象。这个Cookie对象的key是JSESSIONID的值,是新创建出来的SessionID的值。
有Cookie信息

有了Cookie信息之后,每次请求都会把Session的ID以Cookie的形式发送给服务器

request.getSession()

通过Cookie中的id值找到创建好的Session对象,并返回

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值