- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
问题引出 。
解决方法1- 使用cookie 。
在用户登录的时候,服务器可以将用户信息通过cookie的形式保留在浏览器。每当用户访问不同的网页(发送HTTP请求),浏览器都会将该cookie发送给服务器,服务器通过获取cookie的值,在网页上就可以显示当前用户的信息;同时服务器也可以通过cookie(用户信息)找到用户操作用户在数据库中对应的数据.
但是使用cookie会存在以下问题:第一是cookie不能存放大的数据;第二是cookie不安全,不能存放敏感信息;第三,cookie不是跟一个用户关联的。如果一个cookie是长期保存的,那么当其他人打开浏览器时,也可以登录你的账号,因此单单使用cookie来实现也不太理想.
解决方法2- 使用session 。
session是服务器端的技术,也就是说session的数据是保存在服务器端的。服务器在运行时会为每一个用户的浏览器创建一个其独享的session对象(该对象可以理解为一个集合).
由于session为每个用户浏览器独享,所以用户在访问服务器的不同页面时,可以从各自的session中读取/添加数据,从而完成任务.
当用户打开浏览器,访问某个网站,操作session时,服务器就会在内存(在服务端)为该浏览器分配一个session对象,该session对象被这个浏览器独占,如上图 。
这个session对象也可以看做是一个容器/集合,session对象默认存在的时间为30min(在tomcat/conf/web.xml中可以修改) 。
session存储结构示意图 。
你可以把session看做是一容器(类似HashMap),有两列(k-v),每一行就是session的一个属性 。
每个属性包含有两个部分,一个是该属性的名字(String),一个是该属性的值(Object) 。
创建和获取session(api一样) 。
HttpSession session = request.getSession();
第一次调用是创建Session会话,之后调用是获取创建好的Session对象 。
向session添加属性 。
session.setAttribute(String name,Object val);
从session得到某个属性 。
Object obj = session.getAttribute(String name);
从session删除某个属性 。
session.removeAttribute(String name);
isNew(); 判断是不是刚创建出来的Session 。
每个Session都有一个唯一标识的Id值(即JSESSIONID),通过getId()得到Session的会话Id值 。
整个过程如下:
一个浏览器向服务器发送请求,要操作session时,一定会调用request.getSession()方法.
如果服务器在本次会话中,创建了session,则在响应头中将以 Set-Cookie:JSESSIONID=xxxx 的形式返回一个cookie给浏览器保存。下一次浏览器发送请求时,服务器就可以拿到cookie中的JSESSIONID的值,在map中找到该浏览器对应的session,直接操作.
这里的map可以理解为在Tomcat中还维护了一个容器HashMap<String,HttpSession>,这个容器中以JSESSIONID为key,以session为value,完成两者的绑定.
演示Session底层实现机制-创建和读取Session 。
web.xml
<servlet>
<servlet-name>CreateSession</servlet-name>
<servlet-class>com.li.session.CreateSession</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>CreateSession</servlet-name>
<url-pattern>/createSession</url-pattern>
</servlet-mapping>
CreateSession:
package com.li.session;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
import java.io.PrintWriter;
public class CreateSession extends HttpServlet {
@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 {
//System.out.println("CreateSession doPost被调用...");
//1.获取session(同时也可能创建session)
HttpSession session = request.getSession();//注意这个地方已经把sessionId分配了
//2.给session获取id
System.out.println("当前sessionid= " + session.getId());
//3.给session存放一些数据
session.setAttribute("email", "zs@qq.com");
//4.给浏览器发送一个回复
response.setContentType("text/html;charset=utf-8");
PrintWriter writer = response.getWriter();
writer.print("<h1>创建/操作session成功...</h1>");
writer.flush();
writer.close();
}
}
首先访问 http://localhost:8080/cs/createSession
抓包显示:
走的是如下流程:
服务器后端显示:
此时浏览器存储的JSESSIONID变成了新的值:
此时,如果再次访问服务器,就会携带cookie中新的jsessionid给服务器,服务器不再返回jsessionid.
走的是如下流程:
如果redeployTomcat,关闭浏览器并重新打开,直接访问 http://localhost:8080/cs/createSession ,这时候的请求头将不会携带jsessionid(因为关闭浏览器时默认删除了cookie),服务器返回的响应头将会携带一个jsessionid(因为重新发布tomcat,会清空服务器内存,这时请求的资源createSession程序会创建一个session,因此服务器会返回一个与之关联的jsessionid) 。
这时候走的就是如下流程:
web.xml
<servlet>
<servlet-name>ReadSession</servlet-name>
<servlet-class>com.li.session.ReadSession</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ReadSession</servlet-name>
<url-pattern>/readSession</url-pattern>
</servlet-mapping>
ReadSession
package com.li.session;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
import java.io.PrintWriter;
public class ReadSession extends HttpServlet {
@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 {
//System.out.println("ReadSession doPost被调用...");
//演示读取session
//1.获取session,如果没有session也会创建
HttpSession session = request.getSession();
//2.给session获取id
System.out.println("ReadSession 当前sessionid= " + session.getId());
//3.读取属性
Object email = session.getAttribute("email");
if (email != null) {
System.out.println("session属性 email= " + (String) email);
} else {
System.out.println("session中没有 email属性");
}
//3.给浏览器发送一个回复
response.setContentType("text/html;charset=utf-8");
PrintWriter writer = response.getWriter();
writer.print("<h1>读取session成功...</h1>");
writer.flush();
writer.close();
}
}
redeployTomcat,首先在浏览器中访问 http://localhost:8080/cs/createSession (目的是创建一个和浏览器关联的session,因为redeployTomcat会删除服务器的session) 。
然后访问 http://localhost:8080/cs/readSession ,并抓包:
在服务器后台输出如下:第一行输出是我们创建session时获取的sessionid,第二行是我们读取session时获取的sessionid,并获取其属性.
public void setMaxInactiveInterval(int interval) :设置session的超时时间(以秒为单位),超过指定的时长,session就会被销毁.
值为正数的时候,设置session的超时时长.
值为负数时,表示永不超时 。
public int getMaxInactiveInterval() 表示获取session的超时时间 。
public void invalidate() 表示让当前的session会话立即无效 。
如果没有调用 setMaxInactiveInterval(int interval) 来指定session的生命时长,Tomcat会以session的默认时长为准,session的默认时长为30分钟,可以在tomcat目录的conf目录下的web.xml中设置.
Session的生命周期指的是:客户端两次请求的最大间隔时长,而不是累积时长。即当客户端访问了自己的session,session的生命周期将将从0开始重新计算。 (指的是同一个会话两次请求之间的间隔时间) 。
cookie的生命周期指的是累积时长 。
底层:Tomcat用一个线程来轮询会话状态,如果某个会话的空闲时间超过设定的最大值,则将该会话销毁.
最后此篇关于day21-web开发会话技术03的文章就讲到这里了,如果你想了解更多关于day21-web开发会话技术03的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
已关闭。此问题需要 debugging details 。目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and the
我试图查看当天的车辆销量,并创建另外两个列来告诉我过去 10 天的销量和过去 20 天的销量。同一天和同一辆车可能有多个销售。我的目标是获取不同的车辆和日期并查看他们的销售数量。 N 天计数应与该行中
我需要每天 12 小时在 azure 上使用 VM,在 EOD 时关闭并在第二天早上再次启动。我习惯使用 WASABi block 进行自动缩放。 What strategy should I use
我只需要显示天/天的后缀,我该如何实现?它不起作用: java.lang.IllegalStateException: No field to apply suffix to.. privat
尝试使用 HTML 表单和 PHP 更新数据库字段时出现上述错误消息。不确定我的代码有什么问题(我知道它不安全,我只是将它用于个人用途)。我已经检查过,数据库 days 确实存在。 HTML:
谷歌搜索这个,但找不到答案。想知道这两个脚本是否有区别? +3 天: echo date( 'd.m.Y H:i:s', strtotime( '+3 day' ) ); +3 天: echo dat
我试图在某一天显示文本“A Day”,然后在第二天显示“B Day”。我可以使用偶数或奇数函数来执行此操作,然后配置 getDay 对象,但我尝试执行此操作,无论日、月或年如何。 例如,今天可能是“A
在 stack-overflow 中,有一个名为“爱好者”的徽章,通过“连续 30 天每天访问该网站”获得 如何在sql server中编写这个查询? 最佳答案 创建一个表 Id, LastVisit
$('') .attr('label', day) .attr('value', day) if(myDate.getDate(
如果我使用这个函数 pd.DatetimeIndex(dfTrain['datetime']).weekday 我得到了日期,但是我找不到任何给出日期名称的函数...所以我需要将 0 转换为星期一,将
I know I can use relativedelta to calculate difference between two dates in the calendar. However
我正在使用 DayPickerInput,我将其设置为 this (具有 2 天选择器输入的范围)。我想始终显示覆盖,我不想隐藏它。我知道 showOverlay Prop ,但它只在初始渲染期间显示
如何将类添加到 react-day-picker 的今天按钮? 从文档中似乎是可能的: http://react-day-picker.js.org/api/DayPicker#classNames
我需要将一个简单的“3.days”字符串转换为在屏幕上打印“3 days”的内容,该字符串将根据语言使用适当的语言环境来打印单词。 我想可能有一种我似乎找不到的在 Rails 上执行此操作的简单方法。
我想从 Github API GET,每天的贡献数。我正在制作一个网络应用程序,将 github 贡献的数量与我玩的 Dota 2 比赛的数量进行比较。 这张图应该能更清楚地说明事情。 http://
我想在一个月的第三天和最后一天运行一项作业。 下面的 cron 表达式正确吗? “0 0 3 3,L * * ?” 当我在 www.cronmaker.com 中尝试它时,它说这是一个无效的表达式。
我正在尝试为图像中的特定事件设置重复提醒。代码工作正常,但发生了一些正在改变创建事件的事情。请检查以下详细信息。 如果我尝试从循环中设置提醒,它会起作用,但如果重复出现,就会出现上述问题。 检查图像上
我知道新的一天(或小时/分钟,就此而言)没有事件监听器。但在我的 Chrome 扩展程序中,我需要知道新的一天何时开始,这意味着我必须使用 setInterval 函数来确定一天何时发生变化。但是,我
我有一个名为 stockins 的 table 和一个 column stock。因为我想在一周的第一天和一周的最后一天之间找到 max(stock)。 为此,我使用以下查询 select max(s
我们如何将 t.integer :missed 与 t.text :committed 集成,以便 当用户在 :level 中检查他 :missed 3 :committed 天时,他必须重新启动 :
我是一名优秀的程序员,十分优秀!