A:商量个事儿呗
B:嘛事
A:借点钱呗
B: 喂…喂…我这里信号不好…
打开浏览器-》访问应用-》关闭浏览器
用户开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭浏览器,整个过程称之为一个会话。
每个用户在使用浏览器与服务器进行会话的过程中,不可避免各自会产生一些数据,有时服务器要想办法为每个用户保存这些数据。
例如:在浏览器中保存用户的token
但是HTTP(超文本传输协议)是一个基于请求与响应模式的无状态协议。当同一个浏览器多次发送请求到服务器时,服务器并不知道是哪个浏览器发送的请求,即 HTTP 协议的请求无法保存用户状态。
Http无状态主要指 :
针对Http协议,服务器不能自动维护用户的上下文信息,无法保存用户状态;
每次请求都是独立的,不会受到前面请求的影响,也不会影响后面的请求。
由于 HTTP 协议是无状态的,无法保存和跟踪用户状态,所以需要其他的方案来解决问此题,它就是会话技术。常用的会话技术分为两种:
Cookie :浏览端会话技术
Session :服务端会话技术
1)Cookie:将数据保存在浏览器客户端的技术
服务器把每个用户的数据以cookie的形式写给用户各自的浏览器。当用户使用浏览器再去访问服务器中的web资源时,就会带着各自的数据去。这样,web资源处理的就是用户各自的数据了
2)Session:将数据保存在服务端的技术
服务器在运行时可以为每一个用户的浏览器创建一个其独享的session对象,由于session为用户浏览器独享,所以用户在访问服务器的web资源时,可以把各自的数据放在各自的session中,当用户再去访问服务器中的其它web资源时,其它web资源再从用户各自的session中取出数据为用户服务
1)服务端创建cookie对象
2)发送cookie信息到浏览器(HttpServletResponse 中提供void addCookie(Cookie cookie)方法)
例如,响应头中增加 Set-Cookie: name=zhangsan
3)浏览器将得到的cookie信息保存在浏览器端
4)通过浏览器下次访问web应用时,请求数据中会带上cookie信息例如,请求头中 Cookie: name=zhangsan
5)服务器端收到浏览器发送的cookie信息
Cookie类中常用方法:
方法 | |
---|---|
Cookie(String name, String value) | 创建cookie对象的构造方法,value是字符串类型,tomcat8后value可以使用中文 |
String getName() | 取得Cookie的名字 |
String getValue() | 取得Cookie的值 |
void setValue(String newValue) | 设置Cookie的值 |
void setMaxAge(int expiry) | 设置Cookie的最大保存时间,单位秒,即cookie的有效期,默认会话结束,cookie失效。值为 0 时,表示删除该 Cookie |
int getMaxAge() | 获取Cookies的有效期 |
void setPath(String uri) | 设置cookie的有效路径,比如把cookie的有效路径设置为"/aaa",那么浏览器访问"aaa"的web资源时,就会带上cookie |
String getPath() | 获取cookie的有效路径 |
public void cookie1(HttpServletRequest request, HttpServletResponse response){
//创建cookie对象
Cookie cookie = new Cookie("name", "zhangsan");
//如果有相同name值得cookie,后一个会替换前一个cookie内容
//Cookie cookie1 = new Cookie("name", "lisi");
//cookie中的name和value都是字符串类型
//Cookie cookie1 = new Cookie("age", "10");
//tomcat8之后,cookie中支持中文
//Cookie cookie1 = new Cookie("name", "张三");
//通过响应将cookie数据发送到浏览器端
response.addCookie(cookie);
//response.addCookie(cookie1);
}
注意:在tomcat 8 之后,cookie支持中文数据,但是某些特殊字符还是不支持,比如空格、分号等,需要借助URLEncoder.encode(字符串, “utf-8”)进行编码。
这种特殊字符也不用刻意去记,出问题后,直接进行编码
public void cookie1(HttpServletRequest request, HttpServletResponse response){
//获取请求中的cookie数据
Cookie[] cookies = request.getCookies();
if(cookies != null){
for (Cookie cookie2 : cookies) {
// 获取cookie的name和对应的value
System.out.println(cookie2.getName());
System.out.println(cookie2.getValue());
}
}
}
public void cookieTime(HttpServletRequest request, HttpServletResponse response){
Cookie cookie = new Cookie("name", "zhangsan");
//设置cookie的过期时间
//单位秒
// cookie.setMaxAge(60 * 60);
//可以实现删除已有的cookie
// cookie.setMaxAge(0);
//过期时间:会话结束时
cookie.setMaxAge(-1);
response.addCookie(cookie);
}
一个cookie不能超过4k;
一个浏览器最多存300个cookie;
一个站点最多存20个cookie
在WEB开发中,服务器可以为每个用户浏览器创建一个会话对象(session对象),可用用于保存客户端用户的访问状态。
注意:
一个浏览器独占一个session对象
同一浏览器的不同窗口共享同一 Session 对象,但不同浏览器窗口之间不能共享 Session 对象。
Session依赖于cookie
不同的Servlet可以共享同一Session对象中的数据
1)访问应用时,如果创建session(request.getSession()),每个session对象会分配一个id,称谓JSESSIONID
2)服务器会将session的id以cookie的形式发送给浏览器端,浏览器端会存储该id
3)以后再访问应用时,浏览器将session的id发送给服务端
4)服务端收到session的id后,会根据id查找对应的session对象,如果没有找到,创建一个新的session对象
HttpSession中常用方法:
方法 | |
---|---|
String getId( ) | 获取当前的会话ID。每个会话在服务器端都存在一个唯一的标示sessionID,session对象发送到浏览器的唯一数据就是sessionID,它一般存储在cookie中。 |
void setMaxInactiveInterval(int interval) | 指定在无任何操作的情况下,设置会话的最大持续时间,单位是秒,默认30分钟,负数表明会话永不失效 |
int getMaxInActiveInterval() | 获取会话的最大持续时间 |
void setAttribute(String name,String value) | 设定指定名字的属性的值,并将它添加到session会话范围内 |
Object getAttribute(String name) | 在会话范围内获取指定名字的属性的值,返回值类型为object,如果该属性不存在,则返回null |
void removeAttribute(String name) | 删除指定名字的session属性 |
void invalidate() | 使session失效。可以立即使当前会话失效,原来会话中存储的所有对象都不能再被访问 |
long getLastAccessedTime() | 返回上一次发送与此 Session 关联的请求的时间 |
//会根据session的id 查找服务端是否有对应的session对象,如果有,返回session对象;如果没有创建session对象
//创建session对象后,会将JSESSIONID以cookie的形式存在浏览器端
HttpSession session = request.getSession();
//根据JSESSIONID找session对象,如果存在,返回;如果不存在,返回null
// HttpSession session = request.getSession(false);
//session的id,唯一的 JSESSIONID
String id = session.getId();
System.out.println(id);
//默认情况下,JSESSIONID的过期时间是会话结束时,为了能正常访问session对象,需要手动将JSESSIONID存储到cookie中,并设置一个合适的过期时间
Cookie cookie = new Cookie("JSESSIONID", id);
cookie.setMaxAge(30 * 60);
response.addCookie(cookie);
//设置session的过期时间,单位秒,默认30分钟
session.setMaxInactiveInterval(10 * 60);
//向session域中存入数据
session.setAttribute("name", "张三");
// 在一个servlet中存储数据
session.setAttribute("name", "zhangsan");
// 在另一个servlet中读取数据
System.out.println(session.getAttribute("name"));
单位分钟
<session-config>
<session-timeout>10</session-timeout>
</session-config>
session依赖cookie,因为服务器需要根据sessionId,然后找到客户端的session对象,如果浏览器禁用了cookie,就需要对URL进行重写,这样服务器收到的请求中就会带有sessionId。
使用方法:response.encodeURL(String url)
它会判断客户端浏览器是否禁用了Cookie,如果禁用了,那么这个方法会在URL后面追加jsessionid,否则不会追加。
// /day36_session/main;jsessionid=8BE9D12D48CB4C51532A9C007698EEFF
String encodeURL = response.encodeURL(request.getContextPath() + "/main");
response.sendRedirect(encodeURL);
Cookie | Session |
---|---|
Cookie 将数据存放在浏览器端 | Session 将数据存储在服务器端 |
浏览器对 Cookie 的大小和数量有限制 | Session 的大小和数量一般不受限制 |
Cookie 中保存的是字符串 | Session 中可以保存任意类型的对象 |
Cookie 明文传递,安全性低 | Session 存在服务器端,安全性较高 |
Cookie 保存在客户端,不占用服务器资源 | Session 保存在服务端,若并发访问的用户十分多,就会占用大量服务端资源 |
request、session 和ServletContext 称为 Servlet 的三大域对象,它们都能实现资源间共享数据
request | session | ServletContext |
---|---|---|
只对当前请求涉及的 Servlet 有效,通过请求的转发可以实现一次请求中资源之间共享数据。 | session 对本次会话期间的所有 Servlet 都有效,session对象过期,手动调用方法销毁,会话结束 | 对整个 Web 应用内的所有 Servlet 有效 |