基本概念
会话就类似于正常生活中的双方打电话,有一方拿起手机,拨号,另一方接听,然后进行通话,最后结束电话,在web端,就是客户端(浏览器)发出请求,服务器收到请求,发回响应,最后关闭浏览器,在这段时间内产生的多次请求和响应,合起来就叫做浏览器和服务器之间的一次会话。
功能
在一次会话中的多次请求间共享数据。
比如记录用户登陆信息,有些网站在用户第一次登陆时会显示“欢迎来到本网站”,当第二次登入时,则会显示“欢迎回来”,为什么服务器能知道用户已经登录过该页面?原因就是在于服务器会话时保存了一些数据,服务器通过这些数据来判断是否登陆过,从而做出不同的响应。
分类
概述
Cookie技术是一种会话数据管理技术,是把会话数据保存在客户端的。
可以简单理解为是服务器存储在浏览器的一些数据,比如访问某一个网站时会记住用户名,当下一次访问同一个网站时候,服务器会主动去查询这个cookie,如果存在则做相关操作,比如记住密码等。
工作原理
Cookie的工作原理分为几步:
Cookie的快速使用
使用步骤
new Cookie(String name,String value)
发送Cookie对象。使用response.addCookie(Cookie cookie)
3. 服务器获取Cookie,拿到数据。使用Cookie[] request.getCookies()
首先,服务器创建Cookie,并发送给客户端
@WebServlet("/CookieServlet")
public class CookieServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 创建Cookie对象
Cookie cookie = new Cookie("name", "zhangsan");
// 发送Cookie
response.addCookie(cookie);
}
}
使用浏览器访问CookieServlet,查看响应头,此时cookie作为一个响应头发送了过来,如下图
然后接着用浏览器再次访问服务器,查看请求头,如下图
可见,浏览器会将cookie作为请求头发送给服务器,这时服务器可以接收cookie,再做相应处理,下面加上相关代码
@WebServlet("/CookieServlet")
public class CookieServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 创建Cookie对象
Cookie cookie = new Cookie("name", "zhangsan");
// 发送Cookie
response.addCookie(cookie);
// 获取cookie
Cookie[] cookies = request.getCookies();
for (Cookie c : cookies) {
System.out.println(c.getName() + ":" + c.getValue());
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
}
服务器会打印出:name:zhangsan
Cookie常用api
创建Cookie对象
Cookie(String name, String value)
设置Cookie对象
setPath(String url)
:设置cookie的有效路径,也就是指定该cookie访问哪个资源时会发送,其他资源不会发送。
setMaxAge(int expiry)
:设置cookie的有效时长,单位为秒。
setValue(String newValue)
:设置cookie的值。
发送Cookie对象
addCookie(Cookie cookie)
接收浏览器的Cookie
Cookie[] getCookies()
Cookie一些细节
一次可不可以发送多个Cookie?
可以。创建多个cookie对象,多次使用addCookie发送即可。
cookie在浏览器的保存时间
默认情况下,浏览器关闭后,cookie数据被销毁;
要持久化存储,需要使用方法setAge(int expiry)
:
cookie能否存储中文?
建议还是使用URL编码存储,再用URL解码,避免发生错误。
cookie共享问题
假设在一个tomcat服务器中,部署了多个web项目,那这些web项目中cookie能不能共享?
默认情况下是不能共享的。
如果需要共享,可以设置cookie的获取范围,使用
setPath(String path)
如果要共享,可以将path设置为‘/‘
不同tomcat服务器间cookie的共享问题。
可以使用
setDomain(String path)
,设置域名,如果设置一级域名相同,那么多个服务器之间cookie可以共享。比如:
setDomain(".baidu.com")
,那么tieba.baidu.com和news.baidu.com可以共享cookie。
cookie的特点和作用
小程序——记录上次访问的时间
需求:访问一个servlet,如果是第一次访问,则提示"你好,欢迎来到本网站",如果不是第一次访问,则提示"欢迎回来,您上次访问时间为:xxxxx"
@WebServlet("/CookieTest")
public class CookieTest extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 设置编码
response.setContentType("text/html;charset=utf-8");
boolean flag = false;
// 获取Cookie
Cookie[] cookies = request.getCookies();
if (cookies != null && cookies.length > 0) {
for (Cookie c: cookies) {
if (c.getName().equals("lastTime")) {
flag = true;
// 不是第一次登录,设置当前时间,重新发送cookie
Date date = new Date();
SimpleDateFormat sf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
String str_date = sf.format(date);
// URL编码,避免乱码
str_date = URLEncoder.encode(str_date, "utf-8");
c.setValue(str_date);
// 设置Cookie存活时间
c.setMaxAge(60 * 60 * 24 * 7); // 一周
// 发送cookie
response.addCookie(c);
// 响应部分
String value = c.getValue();
value = URLDecoder.decode(value, "utf-8");
response.getWriter().println("<h1>欢迎回来,上次访问时间为:" + value + "</h1>");
break;
}
}
}
// 第一次访问
if(cookies == null || cookies.length == 0 || flag == false) {
// 设置Cookie
Date date = new Date();
SimpleDateFormat sf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
String str_date = sf.format(date);
// 编码
str_date = URLEncoder.encode(str_date, "utf-8");
Cookie cookie = new Cookie("lastTime", str_date);
// 设置存活时间
cookie.setMaxAge(60*60*24*7);
response.addCookie(cookie);
// 响应
response.getWriter().println("<h1>您好,欢迎首次访问</h1>");
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
}
执行结果如下:
第一次访问时:
第二次访问:
概述
Session是另一种会话管理技术,Session将数据保存在服务器端。
Session和Cookie同样是会话管理技术,但一般使用Session,主要是Cookie存在以下局限性:
而Session可以解决以下两个问题。
工作原理
Session的实现是依赖于Cookie的。
Session工作分为以下几步:
Session的相关API
获取HttpSession对象
HttpSession session = request.getSession()
使用HttpSession对象
Object getAttribute(String name)
void setAttribute(String name, Object value)
void removeAttribute(String name)
其他
获取Session对象的ID:String getId()
设置session对象的有效时间:void setMaxInactiveInterval(int interval)
销毁session对象:void invalidate()
Session的一些细节
当客户端关闭后,服务器不关,两次获取的Session是否同一个?
默认情况下不是同一个。
如果需要是同一个,则可以通过创建Cookie,键为JSESSIONID,设置最大存活时间,让cookie持久化存储。
因为session的实现是依赖于cookie的,并且cookie中保存的是session的id。
客户端不关闭,服务器关闭后,两次获取的session是否同一个?
不是同一个。
但为了确保数据不丢失,tomcat会自动完成以下工作:
(IDEA不支持这种操作,因为每次用idea重启tomcat时候,会自动删除catalina_base中的work目录,这样session的序列化文件会被删除)
Session什么时候被销毁?
服务器关闭
session对象调用invalidate()
session默认失效时间:30分钟
选择性配置修改web.xml
<session-config>
<session-timeout>30</session-timeout>
</session-config>
session的特点
Session与Cookie的区别
Session小练习
需求
使用session实现记录上次访问的时间,需求与Cookie中的练习一致。
代码实现
@WebServlet("/SessionTest")
public class SessionTest extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 设置编码
response.setContentType("text/html;charset=utf-8");
// 获取session
HttpSession session = request.getSession();
if (session != null && session.getAttribute("Last_Time") != null) {
// 不是第一次登录,设置当前时间,
Date date = new Date();
SimpleDateFormat sf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
String str_date = sf.format(date);
// URL编码,避免乱码
str_date = URLEncoder.encode(str_date, "utf-8");
session.setAttribute("Last_Time",str_date);
// 响应
String value = (String)session.getAttribute("Last_Time");
value = URLDecoder.decode(value, "utf-8");
response.getWriter().println("<h1>欢迎回来,上次登录时间为:" + value + "</h1>");
} else {
// 第一次登录
Date date = new Date();
SimpleDateFormat sf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
String str_date = sf.format(date);
// URL编码,避免乱码
str_date = URLEncoder.encode(str_date, "utf-8");
session.setAttribute("Last_Time",str_date);
// 响应
String value = (String)session.getAttribute("Last_Time");
value = URLDecoder.decode(value, "utf-8");
response.getWriter().println("<h1>您好,欢迎首次登录</h1>");
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
}
原文:https://www.cnblogs.com/LucasBlog/p/12885629.html