Java Web之Cookie和Session详解

我们知道http协议是无状态的,也就是说就算客户端是第二次访问服务器,服务器还是把此次访当做一个新的访问进行处理,因为服务端并不知道客户端之前是否访问过。而cookie和session则就是为了弥补这一缺陷出现的一种机制。


Cookie

服务端给客户端的数据,存储于客户端(浏览器)。由于是保存在客户端上的,所以存在安全问题,并且cookie是由个数和大小限制的(4KB),所以一般cookie用来存储一些比较小且安全性要求不高的数据,而且一般数据都会进行加密。

我们平时在登录某些网站时,关闭浏览器后再次打开登录,用户名密码等数据会自动填充在表单。
或者我们浏览淘宝的某个商品后,下次再打开发现出现的商品很多都是我们之前浏览的同类商品等。
这些都是cookie的应用场景。

常用方法:

Cookie cookie = new Cookie("account", account);//保存账号数据
cookie.setMaxAge(1*60*60*24);//cookie存在在本地的有效时长(单位为秒) 默认为-1  表示页面关闭cookie就失效
cookie.setDomain("");//设置在某个域名下生效
cookie.setPath("/login.jsp");//设置访问该域名下某个路径时生效
cookie.setMaxAge(0);//cookie中的account
response.addCookie(cookie);//添加到response

 Cookie[] cookies=request.getCookies();//获取cookies
 cookie.getName();//cookie的name
 cookie.getValue();//cookie的value

我们来实现一个记住用户名的小案例

首先写一个登录的界面,我们在页面中获取request中的cookie数组,如果cookie数组中有account的值,则赋给账号输入框。没有的话默认就是空字符串。

代码如下:

<%--
  Created by IntelliJ IDEA.
  User: yzq
  Date: 2018/7/27
  Time: 9:51
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>登录</title>
</head>
<body>

<%
    String path = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()
            + application.getContextPath();

    /*获取request中的cookie*/
    Cookie[] cookies = request.getCookies();
    String cookieAccount = "";

    if (cookies != null) {

        for (Cookie cookie :
                cookies) {
            System.out.println(cookie.getName() + ":" + cookie.getValue());

            /*如果cookie中存储的有account,取出该值 */
            if (cookie.getName().equals("account")) {
                cookieAccount = cookie.getValue();
            }

        }
    }


%>

<form action="<%=application.getContextPath()%>/login">

    <%--将cookie中携带的account值赋值给value--%>
    <input name="account" value="<%=cookieAccount%>"><br>
    <input name="pwd"><br>
    记住密码:<input type="checkbox" name="remember"> <br>
    <input type="submit" value="登录">


</form>

</body>
</html>

我们请求下页面先看一下,首次登录时没有存储账号数据的

这里写图片描述

可以看到默认Cookie中是没有account的。

下面我们实现一下将账号存储到Cookie中

package servlet;

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;

@WebServlet(name = "LoginServlet", urlPatterns = "/login")
public class LoginServlet 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 {


        request.setCharacterEncoding("utf-8");
        response.setCharacterEncoding("utf-8");

        
        String account = request.getParameter("account");
        String pwd = request.getParameter("pwd");

        String isRemember = request.getParameter("remember");

        System.out.println("account=" + account);
        System.out.println("pwd=" + pwd);
        System.out.println("isRemember=" + isRemember);

        if (isRemember != null) {
            Cookie cookie = new Cookie("account", account);//保存账号数据
            cookie.setMaxAge(1*60*60*24);//cookie存在在本地的有效时长(单位为秒) 默认为-1  表示页面关闭cookie就失效
            response.addCookie(cookie);//添加到response
        }
        
    }
}

在LoginServlet中,将账号数据存到cooke中,并将cookie添加到response中,然后在请求登录界面试一下。

这里写图片描述

可以看到,登录成功后我们再次请求登录页面,此时就拿到了account数据了。只要是在有效期内,关闭浏览器再次打开依然是可以获取到account的值的。


Session

在学习jsp的时候我们知道了session是jsp的内置对象,其作用域是在整个会话期间。

我们在之前Cookie的例子会发现cookie中有JSESSIONID这个字段,实际上首次请求网页时在请求头里是没有这个字段的,因为我们并没有创建session,当我们调用request.getSession()时,此时会创建一个session,并且将sessionId保存到cookie中,然后回写给response,所以我们发现首次创建session时的响应头有JSESSIONID这个字段,后面的request默认都会带上JSESSIONID这个字段,而response中则不会再有该字段了。而服务器就能够根据JSESSIONID这个字段值查找对应的session。

我们创建一个SessionServlet ,编写下面代码

package servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

@WebServlet(name = "SessionServlet",urlPatterns = "/session")
public class SessionServlet 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 {

        HttpSession session = request.getSession();//获取session,没有则创建
        String sessionId = session.getId();//获取sessionId

        long createTime = session.getCreationTime();//获取session创建的时间

        long lastTime = session.getLastAccessedTime();//最后一次修改session的时间


        System.out.println("sessionId="+sessionId);
        System.out.println("createTime="+createTime);
        System.out.println("lastTime="+lastTime);
    }
}


运行看看效果

如下图所示,首次请求时响应头中的cookie会有JSESSIONID字段,此时请求头中是没有cookie的,然后再次请求,响应头中则没有了cookie,但是请求头中会有包含JSESSIONID字段的cookie

这里写图片描述

下图是request中cookie默认携带的JSESSIONID

这里写图片描述

但是,如果浏览器禁用了cookie,那么,每次请求都会重新创建session,因为服务器没有获取到JSESSIONID这个值,也无法根据JSESSIONID的值查找相应的session,也就是说,如果客户端禁用了cookie,那么,每次请求得到的sessionId是不一样的。

图示:
先禁用cookie
这里写图片描述

然后再次请求SessionServlet

可以看到,由于禁用了cookie,request中无法携带cookie数据,所以每次请求都会重新创建session,并且将sessionId回写到response的cookie中。
这里写图片描述

跟Cookie不同的是session是将数据存储在服务端的。

常用方法

        HttpSession session = request.getSession();//获取session,没有则创建
        session.getId();//获取sessionId
        session.getAttribute("key");//获取存储的某个值
        session.setAttribute("key","value");//存储数据,value是object类型
        session.getCreationTime();//获取session创建的时间
        session.removeAttribute("key");//移除某个数据
        session.invalidate();//重置session,使session失效
        session.setMaxInactiveInterval(1*60*60);//设置会话的超时时间(单位:秒),默认30分钟
        session.getLastAccessedTime();//最后一次修改session的时间
      

demo

©️2020 CSDN 皮肤主题: 书香水墨 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值