Java Cookie与Session实现会话跟踪详解

软件发布|下载排行|最新软件

当前位置:首页IT学院IT技术

Java Cookie与Session实现会话跟踪详解

CN丶1   2022-11-19 我要评论

概述

要想了解会话跟踪技术,我想我们要先了解一下会话是什么,以及会话跟踪技术存在的意义。

首先我们要说的是:会话。

会话 :见名知意,在现实中我们能想到的是两个人之间的对话,但在web中,对话的两个对象就应该是客户端和服务端,也就是两者产生了连接之后,就产生了会话,直到一端中断此会话,会话结束。值得注意的是:一次会话期间客户端可以发送多个请求给服务端,也就是可以访问多次资源。

出现的问题 :由上我们知道,一次会话可以发送多次请求,但是如果我们使用的是HTTP协议进行资源的传输,那么多次请求之间是无法进行数据共享的。因为HTTP协议是无状态的,也就是无论我们向服务器发送多少次请求,服务器都会认定为是第一次请求。为了解决多次请求之间的数据共享问题,我们引入了会话跟踪技术。

会话跟踪:一种维护浏览器状态的方法,它可以帮助服务器识别多次请求是否来源于同一浏览器,以便实现同一会话中的不同请求之间的数据共享。

会话跟踪的技术实现:

1.客户端会话跟踪技术:Cookie

2.服务端会话跟踪技术:Session

Cookie

客户端会话跟踪技术,将数据保存到客户端,以后每次请求都携带Cookie数据进行访问。

用处:例如当我们第一次访问某服务器时,服务器会发送给我们一个kookie,kookie中存放着一些数据,浏览器将次cookie保存,当我们再次访问次服务器时就会携带保存的cookie,服务器会读取我们我们请求中的kookie,做一些事情。

我们作为后端,也就是服务器端,就要知道kookie的封装、发送和读取的方式。

封装发送 Cookie

在此使用boot工程进行测试,不用boot工程也是没问题的,使用response.addCookie()将创建好的cookie影响出去就行。

@GetMapping
public String cookieTest(HttpServletResponse response){
    //创建cookie
    Cookie cookie = new Cookie("name", "Tom");
    //发送cookie
    response.addCookie(cookie);
    return "send...ok";
}

使用postman进行接口测试:

访问后是可以看到cookie发送成功的

获取客户端请求时携带的cookie

@PostMapping
public String cookieTest1(HttpServletRequest request){
    Cookie[] cookies = request.getCookies();
    String name = cookies[0].getName();
    String value = cookies[0].getValue();
    System.out.println("cookieName:" + name + ",value:" + value);
    return "OK";
}

结果成功打印请求携带的cookie:

Cookie原理

Cookie的实现是基于HTTP协议的,cookie存在于请求头中,查看请求头信息:

会看到cookie的身影。

Cookie由服务器发送给客户端,客户端访问的时候会携带cookie。

Cookie的生命周期

默认情况下,Cookie存储在浏览器内存中,当浏览器关闭,内存释放,则cookie被销毁。

我们可以设置Cookie的生命周期,设置方式:

setMaxAge(int seconds) --seconds设置存储时间,单位为秒

参数:正数:将cookie写入磁盘,持久化存储,到期自动删除。

负数:默认值,浏览器关闭,cookie销毁。

零:删除对应cookie。

Cookie存储中文说明(URL编码介绍)

Cookie不能直接存储中文,会出现乱码问题, 解决:URL编码和解码

在进行Cookie的发送的时候,将中文数据进行URL编码后发送。

在获取Cookie的时候,进行RUL解码操作,获取到中文的Cookie数据。

如下图:以%符号包裹着十六进制就是进行了URL编码后的字符串格式。其原理呢就是将我们的中文字符转为二进制后再转为十六进制加上%包裹而成。

乱码过程:在web传输过程中,实际上是以URL编码后的字符串格式进行传输的,我们在创建cookie发送后,实际上是自动将数据以utf-8字符集进行RUL编码,到Tomcat后以ISO8859-1字符集进行RUL解码操作,两者使用的字符集不一致,导致乱码。

解决:

所以我们可以手动的将字符集进行设置就可以解决次问题。

一般使用cookie也不会使用中文,所以了解即可。

如果想了解URL编码,Java给我们提供了相应工具类:

参考使用如下:

String info =“你好,URL编码!";
string encode = URLEncoder.encode(info,enc: "utf-8");
System.out.println(encode);
string decode = URLDecoder.decode(encode,enc: "IS0-8859-1"");
system.out.println(decode);
//使用iso-8859-1解码后的乱码,字节数依然不变。
//所以,可以将乱码,转为utf-8编码格式的字节。
byte[] bytes = decode.getBytes( charsetName: "IS0-8859-1"");
//再将字节转为字符串即可解决doGet()乱码问题。
string s = new String(bytes,charsetName: "utf-8");
system.out.println(s);

Session

服务器端会话跟踪技术,数据存储在服务端。Session的实现是基于Cookie的。

作用

可以使用session作登录的"记住账号密码"功能,session的数据存储在服务器,更安全,当用户访问登录页面,获取用户session中数据,自动填写登录。

关于Session的方法:

1.setAttribute(String name,Object obj):存储数据到session域中。

2.getAttribute(String name):根据name获取对应值。

3.removeAttribute(String name):根据name删除该session。

存储和读取数据

下面进行测试,不必在意测试写法,只需关注如何创建session,存储数据和获取数据即可。(在表现层使用HttpServletRequest对象调用方法就可以)

@PutMapping
public String sessionTest(HttpServletRequest request){
    //创建session并存储数据
    HttpSession session = request.getSession();
    session.setAttribute("name","Tom");
    return "OK";
}
@DeleteMapping
public String sessionTest1(HttpServletRequest request){
    //获取session
    HttpSession session = request.getSession();
    Object name = session.getAttribute("name");
    System.out.println(name);
    return "OK";
}

测试结果

结果说明:看红框内数据就好,上面的是cookie测试的结果。

session过程:我们看到name和value是不可看到的,因为使用session,数据是存储在服务器的,返回来的相当于一个"钥匙",当我们使用这把"钥匙"去访问服务器,就会进行匹配,匹配成功就可以获取数据。由此可推出一个结论:session的数据存储是更安全的。

Session的钝化和活化

我们知道,session的数据是存储在服务器内存中的,但是有个问题,如果服务器重启,session存储的数据是否还存在?

要说明这个问题,就要提到两个概念:钝化和活化

钝化:服务器正常关闭时,Tomcat会自动将session存储的数据写到磁盘中。

活化:服务器再次启动时,会读取磁盘中的数据到session中。

钝化过程:正常关闭时,Tomcat会自动将Session数据序列化后保存到Session.ser文件中,再次启动服务器时,会重新读取数据。将Session.ser文件删除。

Session的销毁(生命周期)

自动销毁(到期时间)

我相信大家一定有过这样的经历:在某页面操作时,如果在页面待久了未操作,然后点击某按钮或刷新,就会出现类似"登录超时,请重新登录"的提示。这是为什么呢?就是因为Session到期了。你发送的请求被服务器认为是新请求,所以需要重新登录获取操作权限。

在Tomcat中,Session默认到期时间是30分钟。

设置session到期时间的方式有许多种:

1.如果使用的是springboot,可以到application.propertis文件中设置:

server.servlet.session.timeout = 1800 (单位为秒)

2.也可以到web.xml中设置:

<session-config>

<session-timeout>30</session-timeout> (单位为分钟)

</session-config>

3.在编码中通过方法调用的方式:

session.setMaxInactiveInterval(60*30); (单位为秒)

以上情况都是到期后自动销毁。

手动销毁session

调用方法:

session.invalidate();

Cookie 和 Session的对比

两者都是为了解决HTTP协议的无状态的特性,也就是处理一次会话多次请求之间的数据共享的。

两者区别:

1.存储位置:Cookie存储在客户端,Session存储在服务器端。

2.安全性:Cookie不安全,Session安全。

说明:到浏览器可以查看浏览器存储的所有Cookie,数据并不安全。

3.存储容量:Cookie最大3KB,Session对存储大小没有限制。

说明:由于Session数据存储在服务器,数据存在太大对于服务器也会是个负担。

4.到期时间:Cookie可以长期存储,Session默认为30分钟。

对于两者的使用,主要需要考虑安全性和到期时间后选择。

Copyright 2022 版权所有 软件发布 访问手机版

声明:所有软件和文章来自软件开发商或者作者 如有异议 请与本站联系 联系我们