JavaWeb入门-Cookie与Session

什么是Cookie?

Cookie,有时也用其复数形式 Cookies。类型为“小型文本文件”,是某些网站为了辨别用户身份,进行Session跟踪而储存在用户本地终端上的数据(通常经过加密),由用户客户端计算机暂时或永久保存的信息。

1、Cookie 翻译过来是饼干的意思。
2、Cookie 是服务器通知客户端保存键值对的一种技术。
3、客户端有了Cookie 后,每次请求都发送给服务器。
4、每个Cookie 的大小不能超过4kb

平时访问浏览器时,输入账号密码登录一个网页,即使将网页关闭,将浏览器关闭,但下一次访问同一个网页时,是默认进入登录状态的,这就是日常中我们可看到的Cookie应用。

创建Cookie

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-peibKsRB-1644134357794)(C:/Users/12709/AppData/Roaming/Typora/typora-user-images/image-20211123234856879.png)]

protected void createCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    //1 创建Cookie对象
    Cookie cookie = new Cookie("key", "value");
    //2 通知客户端保存Cookie
    resp.addCookie(cookie);
    System.out.println("Cookie创建成功");
    resp.getWriter().write("Cookie创建成功");
}
req.setCharacterEncoding("GBK");
resp.setCharacterEncoding("GBK");
PrintWriter out = resp.getWriter();
Cookie[] cookies = req.getCookies();
for (int i = 0; i < cookies.length; i++) {
    Cookie cookie = cookies[i];
    if (cookie.getName().equals("lastLoginTime")) {
        Long lastLoginTime = Long.parseLong(cookie.getValue());
        Date date = new Date(lastLoginTime);
        out.write(date.toString());
    } 
}
Cookie cookie = new Cookie("lastLoginTime", System.currentTimeMillis() + "");
resp.addCookie(cookie);

Long.parseLong()方法可以将字符串(cookie.getValue())转成long类型,因为实例化Date需要一个long类型的参数!

通过浏览器的控制台,可以看到cookies的信息,部分浏览器在响应网页的时候会不止有一个cookie,所以请求req.getCookies()返回的是一个Cookies数组!

服务器如何获取Cookie

服务器获取客户端的Cookie 只需要一行代码:req.getCookies():Cookie[]!

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wEUvulxT-1644134357795)(C:/Users/12709/AppData/Roaming/Typora/typora-user-images/image-20211124194638566.png)]

CookieUtils工具类:

/**
 * 查找指定名称的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;
}

CookieServlet.findCookie方法:

protected void getCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    Cookie[] cookies = req.getCookies();
    for (Cookie cookie : cookies) {
        resp.getWriter().write("Cookie[" + cookie.getName() + "=" + cookie.getValue() + "]<br>");
    }
        // getName方法返回Cookie的key(名)
    Cookie cookie = CookieUtils.findCookie("key", cookies);
    if (cookie != null) {
        resp.getWriter().write("找到了Cookie: " + cookie.getName());
    }
}

Cookie 值的修改

方案一:
1、先创建一个要修改的同名(指的就是key)的Cookie 对象
2、在构造器,同时赋于新的Cookie 值
3、调用response.addCookie( Cookie );

protected void updateCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    // 方案一:
    // 1、先创建一个要修改的同名的Cookie对象,同时赋于新的Cookie值
    Cookie cookie = new Cookie("key", "values");
    // 2、调用response.addCookie( Cookie ); 通知 客户端 保存修改
    resp.addCookie(cookie);
    resp.getWriter().write("修改了Cookie");

    // 方案二:
    Cookie[] cookies = req.getCookies();
    // 1、先查找到需要修改的Cookie对象
    Cookie key = CookieUtils.findCookie("key", cookies);
    // 2、调用setValue()方法赋于新的Cookie值。
    if (key != null) {
        key.setValue("value1");
    }
    // 3、调用response.addCookie()通知客户端保存修改
    resp.addCookie(key);
    resp.getWriter().write("修改了Cookie");
}

Cookie 生命控制

Cookie 的生命控制指的是如何管理Cookie 什么时候被销毁(删除)!
setMaxAge()

  • 当参数为正数,表示在指定的秒数后过期;

  • 当参数为负数,表示浏览器一关,Cookie 就会被删除(默认值是-1)

  • 当参数为0,表示马上删除Cookie

/**
 * 设置存活1个小时的Cooie
 * @param req
 * @param resp
 * @throws ServletException
 * @throws IOException
 */
protected void life3600(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    // 先找到你要删除的Cookie对象
    Cookie[] cookies = req.getCookies();
    Cookie cookie = CookieUtils.findCookie("key2", cookies);
    // 调用setMaxAge(0);
    cookie.setMaxAge(60 * 60);
    // 调用response.addCookie(cookie);
    resp.addCookie(cookie);
}
/**
 * 马上删除一个Cookie
 * @param req
 * @param resp
 * @throws ServletException
 * @throws IOException
 */
protected void deleteNow(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    // 先找到你要删除的Cookie对象
    Cookie[] cookies = req.getCookies();
    Cookie cookie = CookieUtils.findCookie("key1", cookies);
    // 调用setMaxAge(0);
    cookie.setMaxAge(0);
    // 调用response.addCookie(cookie);
    resp.addCookie(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 发送

protected void testPath(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException, IOException {
    Cookie cookie = new Cookie("path", "testPath");
    cookie.setPath(req.getContextPath() + "/abc");
    resp.addCookie(cookie);
    resp.getWriter().write("已设置cookie的路径属性");
}

当用户访问cookie.html时,因为工程路径是http://ip:port/Cookie/,所以添加的名为path的cookie不会在控制台中显示出来,但是只要进入http://ip:port/Cookie/abc/路径下,该cookie就会显示出来,并且,任何path属性为工程路径的cookie仍然能够显示!

Cookie练习: 免输入用户名登录

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-shb8xojx-1644134357795)(C:/Users/12709/AppData/Roaming/Typora/typora-user-images/image-20211124204500353.png)]

login.jsp 页面:

<form action="login" method="get">
    用户名:<input type="text" name="username" value="${cookie.username.value}">
    <br>
    密码:<input type="password" name="password" id="password">
    <br>
    <input type="submit" value="提交">
</form>

LoginServlet 程序:

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    String username = req.getParameter("username");
    String password = req.getParameter("password");
    if (username.equals("admin") && password.equals("as1234")) {
        Cookie cookie = new Cookie("username", username);
        cookie.setMaxAge(60 * 60 * 24 * 7);
        resp.addCookie(cookie);
        System.out.println("登陆成功");
    } else {
        System.out.println("登录失败");
    }

cookie是EL表达式的11个隐藏对象的其中一个,如同HttpServletRequest.getCookies(),返回值为一个Map集合,存储了所有Cookie的键值对!

JSTL并没有提供设定cookie的动作,因为这个动作通常都是后端开发者必须去做的事情,而不是交给前端的开发者。假若我们在cookie中设定一个名称为userCountry的值,那么可以使用${cookie.userCountry}来取得它。

Session

什么是 Session 会话?

Session,在计算机中,尤其是在网络应用中,称为“会话控制”。Session对象存储特定用户会话所需的属性及配置信息。

这样,当用户在应用程序的Web页之间跳转时,存储在Session对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。

当用户请求来自应用程序的 Web页时,如果该用户还没有会话,则Web服务器将自动创建一个 Session对象。当会话过期或被放弃后,服务器将终止该会话。Session 对象最常见的一个用法就是存储用户的首选项。

例如,如果用户指明不喜欢查看图形,就可以将该信息存储在Session对象中。有关使用Session 对象的详细信息,请参阅“ASP应用程序”部分的“管理会话”。

1、Session 就一个接口(HttpSession)

2、Session 就是会话。它是用来维护一个客户端和服务器之间关联的一种技术

3、每个客户端都有自己的一个 Session 会话

4、Session 会话中,我们经常用来保存用户登录之后的信息

如何创建和获取Session

创建和获取Session的方法同为一个:request.getSession()

第一次调用是:创建Session 会话!之后调用都是:获取前面创建好的Session 会话对象!

而每个会话都有一个身份证号,也就是ID 值,而且这个ID 是唯一的,getId()方法可以得到Session 的会话id 值。

注意会话状态仅在支持cookie的浏览器中保留。

public class SessionTest01 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");
        HttpSession session = req.getSession();
        session.setAttribute("name", "ayin");
        String id = session.getId();
        if (session.isNew()) {
            resp.getWriter().write("session创建成功:" + id);
        } else {
            resp.getWriter().write("session已存在:" + id);
        }
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
session已存在:703A717FABBAC7F9196FD6BF04500FBE

每个浏览器会在打开的一瞬间就完成创建session对象这一个操作,并且不同的浏览器,session对象也不同!

session.isNew() 可以判断session对象是否为新创建的对象,session.setAttribute() 可以在session域中存储一些节点数据,也就是说,同理于ServletContext,我们可以在另一个类中获取session中的数据!

Session 域数据的存取:

* @param resp
* @throws ServletException
* @throws IOException
*/
protected void setAttribute(HttpServletRequest req, HttpServletResponse resp) throws ServletException,
IOException {
    req.getSession().setAttribute("key1", "value1");
    resp.getWriter().write("已经往Session 中保存了数据");
}
/**
* 获取Session 域中的数据
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void getAttribute(HttpServletRequest req, HttpServletResponse resp) throws ServletException,
IOException {
    Object attribute = req.getSession().getAttribute("key1");
    resp.getWriter().write("从Session 中获取出key1 的数据是:" + attribute);
}

当然,也可以往session中存储一个对象:

Person name = (Person) session.getAttribute("name");

Session生命周期控制

public void setMaxInactiveInterval(int interval)方法,可以设置Session 的超时时间(以秒为单位),超过指定的时长,Session
就会被销毁。
当值为正数的时候,设定Session 的超时时长,负数表示永不超时(极少使用)!

  • public int getMaxInactiveInterval() 获取Session 的超时时间
  • public void invalidate() 让当前Session 会话马上超时无效

Session 默认的超时时间长为30 分钟。
因为在Tomcat 服务器的配置文件web.xml 中默认有以下的配置,它就表示配置了当前Tomcat 服务器下所有的Session
超时配置默认时长为:30 分钟。

<session-config>
    <session-timeout>30</session-timeout>
</session-config>

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

在设置文件web.xml中,可以设置session的失效时间:

<session-config>
    <!-- 设置session失效时间为15分钟-->
    <session-timeout>15</session-timeout>
</session-config>

如果只修改个别Session 的超时时长,可以使用setMaxInactiveInterval(int interval)来进行单独的超时时长!

Session超时的概念

假设此时按照以下代码实例设置Session对象的超时时长为3秒:

rotected void life3(HttpServletRequest req, HttpServletResponse resp) throws ServletException,
IOException {
    // 先获取Session 对象
    HttpSession session = req.getSession();
    // 设置当前Session3 秒后超时
    session.setMaxInactiveInterval(3);
    resp.getWriter().write("当前Session 已经设置为3 秒后超时");
}

超时概念图如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PdKlqpWl-1644134357796)(C:/Users/12709/AppData/Roaming/Typora/typora-user-images/image-20211126230520910.png)]

按照上图所示,当客户端持续发起请求时,Session对象的超时时间属性timeout会一直被重置成3秒,也就是说,只要持续不间断发起请求,Session对象就可能永远不会超时!当客户端不再发起请求(闲置时),Session便会正常经过3秒后超时!

Session 马上被超时示例:

protected void deleteNow(HttpServletRequest req, HttpServletResponse resp) throws ServletException,
IOException {
    // 先获取Session 对象
    HttpSession session = req.getSession();
    // 让Session 会话马上超时
    session.invalidate();
    resp.getWriter().write("Session 已经设置为超时(无效)");
}

关于Session和Cookie的区别

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

在一些场景中,例如:保存一个用户的信息,购物车信息,在整个网站中经常会使用的数据等,都会保存在Session中!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值