博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
servlet对象是在服务器端还是在客户端被创建?_Servlet编程之会话管理
阅读量:1522 次
发布时间:2019-04-21

本文共 6274 字,大约阅读时间需要 20 分钟。

c6dbb54f8638927a2f07ea1649a5a4e6.png

一、什么是会话管理?

生活中人与人进行谈话,就是一次会话,会话的内容我们会自己记住。而客户端与服务器端的交互也是会话,会话的内容好像也能被客户端和服务器端记住。

示例一:我们平时使用账号密码登录某个网站,一旦登录,这个网站似乎就能记住我们,以至于再次打开该网站,它就能识别出我们。

示例二:我们进入电商网站浏览商品时,电商网站可以记住我们的历史浏览商品。

所以,简单来说,会话管理就是管理浏览器客户端和服务器端之间会话过程中产生的会话数据。

浏览器客户端和服务器端的会话管理涉及的技术有Cookie技术Session技术,两者的区别在于:

  • Cookie技术将会话数据保存在浏览器客户端
  • Session技术将会话数据保存在服务器端

二、Cookie技术

2.1、Cookie技术的特点

  • Cookie技术将会话数据保存在浏览器客户端。
  • Cookie数据只能是非中文的字符串类型的数据
  • 浏览器可以保存多个Cookie,但是浏览器一般只允许存放300个Cookie,每个站点最多存放20个Cookie
  • 每个Cookie的大小限制为4KB

2.2、Cookie技术的原理

浏览器客户端第一次向服务器发送请求时,服务器接收到请求后,会创建一个Cookie对象,把会话数据(比如浏览器发送过来的用户账号和密码)存储到Cookie对象中,最后把Cookie对象发送到浏览器。浏览器会接收这个Cookie对象,并保存它。

当浏览器第二次向相同的服务器路径发送请求时,会将上次保存的Cookie对象发送给服务器,服务器检查到这个Cookie对象,就能从中取出会话数据,这样服务器就能知道是原先的用户在访问网站。

2.3、Cookie技术核心API

  • Cookie(String name, String value) —— 用户创建Cookie对象的构造函数
  • void setPath(String uri) —— 设置cookie的有效访问路径
  • void setMaxAge(int expiry) —— 设置cokie的有效时间
  • void setValue(String newValue) —— 设置cookie的值
  • Cookie[] request.getCookies() —— 接收cookie
  • void response.addCookie(Cookie cookie) —— 发送cookie到浏览器端保存

①关于有效路径

Cookie对象中包含有有效路径,比如使用谷歌浏览器访问百度以后,打开谷歌浏览器的设置->内容设置->Cookie->查看所有Cookie和网站,查看http://www.baidu.com的Cookie,就会显示有效路径:

1be7cfc7e3b7908afffedf2344188c83.png

浏览器只有访问该域名的有效路径时,才会向该服务器发送Cookie信息,也就是访问http://www.baidu.com/时才会发送Cookie信息给服务器。

上面的setPath()就是用于设置有效路径,使用该方法设置成什么,浏览器中保存的Cookie中显示的有效路径就是什么。

②设置Cookie的有效时间

Cookie不是永远保存在浏览器中的,需要我们使用上面的setMaxAge(int expiry)来设置,可以传入正整数、负整数和零:

  • 正整数:表示Cookie数据保存在浏览器所在机器的硬盘中,正整数数值表示保存的时间,比如传入60,则Cookie数据在硬盘中将保存60秒
  • 负整数:无论传入什么负整数,Cookie数据都将保存在浏览器的内存中,浏览器一关闭,Cookie就丢失了
  • 零:表示删除同名的Cookie数据

2.4、示例

示例:让网站具有提示用户上次访问的时间的功能

源代码(Servlet):

package demo1;import java.io.IOException;import java.text.SimpleDateFormat;import java.util.Date;import javax.servlet.ServletException;import javax.servlet.http.Cookie;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;public class LoginServlet extends HttpServlet{
@Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8"); SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd-hh:mm:ss"); String currentTime = format.format(new Date()); Cookie[] cookies = request.getCookies(); // 获取浏览器传送过来的Cookie if(cookies == null) {
// 如果cookies为空,则表示是浏览器第一次访问本网站,那么就新创建一个Cookie对象,发送给浏览器 Cookie cookie = new Cookie("lastTime", currentTime); cookie.setMaxAge(30*24*60*60); response.addCookie(cookie); response.getWriter().write("您是第一次访问本网站,当前时间为:" + currentTime); }else {
// 如果cookies不为空,lastTime不为空,且cookies中有名为lastTime的cookie信息,则向浏览器返回 // 上次登录的时间的信息,并更新lastTime for(Cookie cookie : cookies) {
if("lastTime".equals(cookie.getName())) {
response.getWriter().write("您上次访问本网站的时间为:" + cookie.getValue() + ", 当前时间为: " + currentTime); cookie.setValue(currentTime); cookie.setMaxAge(30*24*60*60); response.addCookie(cookie); } } } }}

第一次登录时只提示当前时间:

b6031c02d5fbbca6ce8138f3bb649342.png

第二次登录时除了提示当前时间,还提示上次访问该网站时的时间:

245a72143e6bbb6fc84c487f274f4a55.png

在浏览器中查看Cookie,可以知道浏览器保存了一个名为lastTime的Cookie:

a5b49760e2bbbaf47abe6b935aa30d2a.png

三、Session技术

3.1、Session技术的特点

  • Session技术将会话数据保存再服务器端(内存中)
  • Session可以保存对象
  • Session可以存储中文字符串
  • Session可以保存超过4kb的会话数据

3.2、Session技术的原理

浏览器第一次访问服务器时,服务器会新建并保存一个session对象,并在该session对象中保存会话数据。然后服务器会创建一个和该session对象对应的名为JSESSIONID的Cookie对象发给浏览器,浏览器将保存这个cookie对象。

浏览器再次访问服务器时,会往服务器发送那个名为JSESSIONID的Cookie对象,服务器根据该Cookie对象的值查询对应的session对象,然后再取出会话数据。

所以,session对象和会话数据都是保存再服务器端的,而名为JSESSIONID的cookie对象就是服务器端分配给浏览器的一把钥匙,一把用于取双方会话数据的钥匙。

3.3、Session技术核心API

  • HttpSession getSession() —— 得到session对象
  • HttpSession getSession(boolean create) —— 当create参数为true时,如果获取不到对应session对象就为浏览器创建一个session对象;如果create参数为false时,如果获取不到对应session对象就返回null。
  • void setAttribute(String name, Object value) —— 保存会话数据到session对象
  • Object getAttribute(String name) —— 从session对象中获取会话数据
  • void removeAttribute(String name) —— 清除session对象中对应的会话数据
  • void setMaxInactiveInterval(int interval) —— 设置session的有效时间,默认情况是30分钟
  • void invalidate() —— 销毁session对象
  • String getId() —— 得到session编号

3.4、示例

示例:模仿用户登录网站,登录一次就可以识别该用户

源代码:

login.html:

Insert title here
用户名:
密码:
提交:

fail.html:

Insert title here
登录失败,用户名或密码不正确!

LoginServlet:

import java.io.IOException;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import javax.servlet.http.HttpSession;public class LoginServlet extends HttpServlet{
@Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String userName = request.getParameter("userName"); String password = request.getParameter("password"); if("admin".equals(userName) && "123456".equals(password)) {
// 账号密码验证成功,则通过session保存会话数据,并重定向到成功页面 HttpSession session = request.getSession(); session.setAttribute("userName", userName); response.sendRedirect(request.getContextPath() + "/SuccessServlet"); }else {
// 账号密码验证失败,则重定向到失败页面 response.sendRedirect(request.getContextPath() + "/fail.html"); return; } } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response); }}

SuccessServlet:

import java.io.IOException;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import javax.servlet.http.HttpSession;public class SuccessServlet extends HttpServlet{
@Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8"); HttpSession session = request.getSession(false); if(session != null) {
String userName = (String) session.getAttribute("userName"); response.getWriter().write("
Hello,"+userName+"! 登录成功
"); }else {
response.getWriter().write("
无效页面!
"); } }}

首先使用浏览器访问login.html页面,输入用户名admin,和密码111111(故意输错密码):

f549878879cc768aeb5dd2f66d0f51aa.png

提交以后,返回提示登录失败的页面:

ca50f47f6383e0be484a40ab0a171dbc.png

重新登录,输入用户名admin,密码123456:

5be491b8debf7458bbdc4c541aad1c18.png

查看浏览器中的cookie,发现果然多了一个名为JSESSIONID的Cookie:

68373e8e6ee264e5a7d716564100e75b.png

然后,在浏览器打开一个新的标签页,输入http://localhost:8080/SessionProject/SuccessServlet,可以发现直接登录成功,说明服务器已经识别了这个浏览器中的admin用户:

3893f662515d97bb08eff278da89b028.png

转载地址:http://umnby.baihongyu.com/

你可能感兴趣的文章
洛谷 P2580 于是他错误的点名开始了【字典树/Map】
查看>>
HDU 3336 Count the string【KMP的next数组性质】
查看>>
洛谷 P1196 [NOI2002]银河英雄传说【带权并查集】
查看>>
HDU 4825 Xor Sum【01字典树/贪心】(两数最大/最小异或和)
查看>>
洛谷 P4551 最长异或路径【01字典树/贪心】
查看>>
LeetCode C++ 622. Design Circular Queue【设计/循环队列】中等
查看>>
LeetCode 921. 使括号有效的最少添加(栈)
查看>>
LeetCode 1018. 可被 5 整除的二进制前缀
查看>>
LeetCode 961. 重复 N 次的元素
查看>>
LeetCode 925. 长按键入(双指针)
查看>>
LeetCode 1309. 解码字母到整数映射
查看>>
动态规划应用--最长递增子序列 LeetCode 300
查看>>
LeetCode 53. 最大子序和(动态规划)
查看>>
图Graph--拓扑排序(Topological Sorting)
查看>>
图Graph--最短路径算法(Shortest Path Algorithm)
查看>>
LeetCode 674. 最长连续递增序列
查看>>
LeetCode 70. 爬楼梯(动态规划)
查看>>
数据结构--位图 BitMap
查看>>
朴素贝叶斯算法--过滤垃圾短信
查看>>
向量空间 Vector Space -- 推荐系统
查看>>