JSP会话技术
-
- 1.前言
- 2.会话概述
-
- ① 基于Cookie的会话管理
- ② 基于 HttpSession 的会话管理
- 3. Cookie对象
-
- ① 背景:
- ② 在浏览器的HTTP头部中怎么找到Cookie的信息?
- ③ Cookie存储在什么地方?
- ④ Cookie格式:
- ⑤ Cookie原理
-
- 1. Cookie是什么:
- 2. Cookie包含什么:
- 3. Cookie由谁创建,由谁存放:
- 4. Cookie的数量:
- 5. Cookie存在的要求:
- 6. Cookie的工作过程
- 7.设置过期时间:expires属性
- 8.设置域名:domain属性
- 9.设置路径:path属性
- ⑥ Cookie常用方法
-
- 1.创建Cookie
- 2.将创建的Cookie添加到Http响应头中
- 3.设置/读取Cookie 名/值对
- 4.设置/读取Cookie超时时间
- 5.设置/读取Cookie域名
- 6.设置/读取Cookie路径
- 4. Session对象
-
- ① 前言
-
- 1.存储位置
- 2.存储限制
- 3.带宽限制
- 4.有效期
- 5.安全性
- ② Session原理
-
- 1.基于Cookie
- 2. URL重写
- 3.隐藏表单域
- ③ Session对象常用方法
-
- 1.获得HttpSession对象
- 2.操作Session属性
- 3.销毁Session
- 4. Session过期
1.前言
为什么要有JSP会话技术?
Http是一种无状态的协议,意味着Web应用每一次请求之间都是相互独立的,后一次请求无法知道前一次的信息。会话技术可以对同一个网站的多个请求进行管理。创建了一个会话,只要没有销毁会话,会话就可以跟踪记录整个会话中的活动,并在一个会话中多个请求中存储和传递数据。
JSP一共有四种会话机制:Request 、Session 、 Cookie 、 Application,本文针对Session,Cookie进行讲解
2.会话概述
① 基于Cookie的会话管理
- Cookie是客户端技术
- web应用把用户的每个数据以Cookie的形式发送给浏览器,当用户使用浏览器访问web应用是,会带上这些Cookie,这样web应用从得到的Cookie中取出数据为其服务
② 基于 HttpSession 的会话管理
- HttpSession 是服务端技术
- 服务器在运行时为每个用户的浏览器创建一个其独享的HttpSession对象,对象存放在服务器中,Session_id发送给浏览器
- 由于独享,所以可以把用户的数据存放在各自的Session域中
- 当用户访问服务器中该web应用的其他资源时,web资源再从用户各自的Session域中取出数据为其服务
3. Cookie对象
① 背景:
现在所有的主流浏览器都支持Cookie,如 IE、Chrome、Firefox 等等 都支持。
② 在浏览器的HTTP头部中怎么找到Cookie的信息?
响应报文首部的 Set - Cookie:
- 当服务器给客户端发送的响应信息中包括了 Set - Cookie头部,意思就是指示客户端建立一个 Cookie
请求报文首部的 Cookie:
- 当客户端向服务器发送一个请求时,要自动带上服务器所指示创建的Cookie,直到这个Cookie过期
③ Cookie存储在什么地方?
内存:
- 如果Cookie的生存时间为这个会话期间,则存储在内存,浏览器关闭时,自动清除Cookie
硬盘:
- 即使关闭了浏览器,即会话已经结束,Cookie也不会清除,而是保存在了硬盘中,下一次打开浏览器访问网站时,会从硬盘中找到指定Cookie,取出,发送到服务器
④ Cookie格式:
服务器在响应报文头部设置的Cookie格式:
Set - Cookie: NAME = VALUE; Experes = DATE; path = PATH; Domain = DOMAIN_NAME; SECURE
NAME = VALUE:
- 每个Cookie必须要有
- NAME 是该Cookie的名称,VALUE是该Cookie的值
Experes = DATE:
- Experes 变量是一个只写变量,记录了Cookie的有效终止日期
- 该变量可以没有,则Cookie仅保存在内存中,随着浏览器的关闭而自动消失
path = PATH:
- 规定了web服务器上哪些路径下的页面可以获得服务器设置的Cookie
- 如果用户输入的URL中,路径部分从第一个字符开始包含path属性的字符串,浏览器就认为通过检查
- Path属性可以为 path = / ,则表示web服务器上所有的资源均可读取浏览器发送过来的该Cookie
- 该属性可以没有,服务器发送的响应报文中Set - Cookie未包含该属性,则默认该属性为服务器传给浏览器这样的路径名
⑤ Cookie原理
1. Cookie是什么:
Cookie在客户端实际上是一小段文本信息
在服务器中是一个java类
2. Cookie包含什么:
Cookie 主要包括:名称 、 值 、 过期时间 、 域名 、 地址
Cookie类定义如下:
public class Cookie implements Cloneable, Serializable { private static final CookieNameValidator validation;private static final long serialVersionUID = 1L;private final String name;private String value;private int version = 0;private String comment;private String domain;private int maxAge = -1;private String path;private boolean secure;private boolean httpOnly;public Cookie(String name, String value) { ...}public void setComment(String purpose) { ...}public String getComment() { ...}public void setDomain(String pattern) { ...}public String getDomain() { ...}public void setMaxAge(int expiry) { ...}public int getMaxAge() { ...}public void setPath(String uri) { ...}public String getPath() { ... }public void setSecure(boolean flag) { ...}public boolean getSecure() { ...}public String getName() { ...}public void setValue(String newValue) { ...}public String getValue() { ...}public int getVersion() { ...}public void setVersion(int v) { ...}public Object clone() { ...}public void setHttpOnly(boolean httpOnly) { ...}public boolean isHttpOnly() { ...}static { ...} }
3. Cookie由谁创建,由谁存放:
Cookie 由服务器创建,由客户端存储
4. Cookie的数量:
一个服务器可以创建多个Cookie ,所以客户端可以有多个Cookie的域名属性指向同一服务器
5. Cookie存在的要求:
每个Cookie所存放的的数据不可以超过 4 KB
每个Cookie文件夹充分的Cookie不得超过300个
每个域名创建的Cookie不得超过20个
一个或多个Cookie会根据一定的规则存放在同一Cookie文件夹下
浏览器用户可以设定不使用Cookie
6. Cookie的工作过程
7.设置过期时间:expires属性
如果不设置过期时间,则Cookie的生命周期为浏览器会话周期,只要关闭浏览器窗口,该Cookie就消失了,生命周期为浏览器会话周期的Cookie称为会话Cookie,会话Cookie存在内存中;
如果设置过期时间,浏览器就会把Cookie存在硬盘中,浏览器关闭后再打开,Cookie会从硬盘中取出,仍然有效,直到超过设定的过期时间;
Cookie可以在同一浏览器的不同窗口共享,但不可以在不同浏览器中共享
8.设置域名:domain属性
正常情况下,Cookie只被送回一开始向用户发送Cookie的服务器
如果domain为空,则domain被设置为提供Cookie的web服务器,
如果domain不为空,domain设置与提供Cookie的web服务器域名不同,则此Cookie会被忽略;
Cookie只会区分域名,不会区分端口号
9.设置路径:path属性
控制页面中哪些对服务器的访问可以触发Cookie的发送
如果没有设置path,则Cookie会在所有对此服务器的Http传送时发送
如果设置path,如 path = /directory,则浏览器在访问 /directory下面的网页时Cookie才会被发送
⑥ Cookie常用方法
1.创建Cookie
package javax.servlet.http;
//Cookie类
public Cookie(String name, String value) {
validation.validate(name);this.name = name;this.value = value;}
package com.a.text;
//text测试类
public class text(){
String name1 = "user1";String value1 = "123456";Cookie cookie1 = new Cookie(name1, value1);
}
-
name属性定义了Cookie的名称,而且是Cookie的标识,多个Cookie中name属性不可相同,如果相同,后者会把前者覆盖掉
-
value属性定义了Cookie的值
-
不同Cookie版本对value属性的字符限制也不同,
Cookie Version 0不可使用特殊字符,如空格、方括号、圆括号、等号、逗号、双引号、斜杠、@、冒号、问号、分号
Cookie Version 1放宽了限制,可以使用这些字符,但是因为仍然没有所以浏览器都支持,所以这些字符尽量不要使用
2.将创建的Cookie添加到Http响应头中
Http响应头中添加一个set - Cookie字段,使用response接口中定义的addCookie方法,cookie加入到Http响应中
String name1 = "user1";
String value1 = "123456";
Cookie cookie1 = new Cookie(name1, value1);
String name2 = "user2";
String value2 = "789012";
Cookie cookie2 = new Cookie(name2, value2);response.addCookie(cookie1);
response.addCookie(cookie2);
3.设置/读取Cookie 名/值对
设置Cookie的值
public void setValue(String newValue) {
this.value = newValue;
}
读取Cookie名称
public String getName() {
return this.name;
}
读取Cookie值
public String getValue() {
return this.value;
}
request接口中定义了一个public Cookie[] getCookies();方法,从请求中得到Cookie的集合cookies
以下演示了如何得到Cookies,cookie,Name,Value
PrintWriter out = response.getWriter();
Cookie cookies[] = request.getCookies();
Cookie cookie = null;
if(cookies != null){
for(int i = 0;i < cookies.length;i++){
cookie = cookies[i];out.println("cookie name:" + cookie.getName() + " ");out.println("cookie value" + cookie.getValue() + "<br/>");}
}
4.设置/读取Cookie超时时间
**public void setMaxAge(int expiry);**方法用于设置cookie的最大保存时间,即cookie的有效时间
public void setMaxAge(int expiry) {
this.maxAge = expiry;
}
//expiry属性表示有效时间,以秒为单位,如果为一天,则expiry取值为24*60*60
//如果expiry为负数,则为会话cookie,关闭浏览器cookie删除
//如果expiry等于0,则删除cookie
public int getMaxAge();方法用于读取超时时间,返回过期之前的最大时间,以秒为单位
public int getMaxAge() {
return this.maxAge;
}
客户端要想在过期时间之前删除本地Cookie,则可退出登录之类的操作,服务器会设置cookie的expiry属性为0,如:
Cookie cookies[] = request.getCookies();
Cookie cookie = null;
for(int i = 0;i < cookies.length;i++){
cookie = cookies[i];if(cookie.getName().equals("user1")){
cookie.setMaxAge(0);response.addCookie(cookie);}
}
5.设置/读取Cookie域名
**public void setDomain(String pattern); ** 方法设置Cookie有效域
pattern 字符串表示域名,字符串必须以 ( " . " )开始
public String getDomain(); 方法读取Cookie有效域
实例如下:
Cookie cookie1 = new Cookie("user1", "123456");
cookie1.setDomain(".www.ok.com");
response.addCookie(cookie1);
6.设置/读取Cookie路径
public void setPath(String uri); 方法用于设置Cookie路径
如果在服务器端不设置Cookie实例的该属性,则默认为创建该Cookie的servlet的URL
public String getPath(); 方法用于读取Cookie路径
不论是getPath还是setPath,url都是相对于服务器存放应用文件夹的根目录而言,如 相对于Tomcat的webappps文件夹而言
正常情况下,cookie只在一个应用中共享,
没有设置path属性,则该cookie只由创建它的应用获得,
如果要在其他应用中共享,则需要设置path,多次设置path,以最后一条为准,设置path后, 该cookie只有在访问设置的应用路径时才会发送该cookie
若path设置为 " / " ,则客户端在访问根目录下的所有文件时都会发送该cookie,即为webapps下的所有应用共享此cookie
//该程序所在的应用为"/appA",所在的servlet为"servletA",完整路径为"/appA/servletA"
Cookie cookie1 = new Cookie("user1", "123456");
cookie1.setPath("/appB/");
response.addCookie(cookie1);
//现在设置的该cookie发送到客户端后,客户端在访问"/appB"应用时才会发送该cookie到服务器的"/appB"应用
//虽然该cookie是由"/appA"应用所创建,但是coookie发送到客户端后,只有访问"/appB"应用下的路径时,浏览器才会发送该cookie的信息
4. Session对象
① 前言
Session 一般称为会话
Session 机制是一个服务器端的机制,与Cookie不同,Cookie机制是一个客户端机制
Session 与 Cookie 的作用都是为了访问用户与后端服务器的交互状态。但Session 与 Cookie 有些不同,从以下几个方面比较:
1.存储位置
Cookie 存储在客户端 Session 存储在服务器端
简单来说,当登录一个网站时, 如果Web服务器端使用的是Session ,那么所有的数据都保存在服务器上,客户端每次请求服务器时都会发送当前会话的Session ID,服务器端根据当前Session ID,判断相应的数据标志,以确定用户是否登录或具有某种权限。
如果,浏览器使用的是cookie,那么所有的数据都保存在浏览器。比如登录以后服务器设置了cookie用户名,那么再次请求服务器时,浏览器会将用户一块发送给服务器,这些变量有一定的特殊标记。服务器会解释为Cookie变量,以确定用户是否登录或具有某种权限。
2.存储限制
Cookie要求每个客户端最多保存300个Cookie。每个域名下最多有20个cookie,而每个cookie的大小最大为4KB,不过不同的浏览器都有各自的实现
而Session 通常存储在服务器内存中,没有明确的大小限制,但当访问增多时,会降低服务器的性能。
3.带宽限制
使用cookie来传递数据,随着cookie个数增多和访问量的增加,它占用的网络带宽也会越大。Session 只需要在请求中携带 Session ID 即可,不会影响网络带宽。
4.有效期
两者同样都有有效期的说法,Session 是存储在服务器上的,过期与否取决于服务器端的设定。cookie是存储在客户端的,过期与否是在Cookie生成时设定的。
5.安全性
两者都有可以用来存放私密的东西,但也都存在安全性问题。
Session 的数据是存储在服务器上面的,数据无法构造但如果能够获取某个登录用户的 Session ID 通过伪造 Session ID 的请求, 可以仿造用户身份。
Cookie如果设置有效时间,那么他会被保存在客户端的硬件硬盘上,如果将cookie复制到其他机器的浏览器的目录下,那么登录该网站时就是用你的身份登录的,cookie所以可以可以伪造。
② Session原理
当程序需要为某个客户端的请求创建一个Session 时,服务器首先检查这个客户端的请求里是否已包含了一个 Session 标识,称为 Session ID,如果客户端请求不包含 Session ID ,则为此客户端创建一个 Session ,并且生成一个于此 Session 相关联的 Session ID , Session ID 的值是一个既不会重复又不会被找到规律以仿造的字符串,这个 Session ID 将在本次响应中被返回给客户端保存,客户端在后续的访问中都会在请求中包含 Session ID,服务器就按照 Session ID 把这个 Session 检索出来使用。但如果没有检索到客户端提交的 Session ID ,说明 Session ID 说明 Session 被注销或超时,服务器端会新建一个 Session ,并把 Session ID 发送给客户端,客户端会使用新的 Session ID 与服务器交互, Session 的工作原理如下图所示
1) 客户端首次向服务器端发送请求,不包括 Session ID
2) 服务器端为其创建一个Session 对象,保存用户的有关信息,这些信息不予其他客户端共享
3) 每个Session 都有唯一的 Session ID ,并通过响应报文发送给客户端浏览器,示例如下:
在客户端的浏览器中,响应报文中可看到如下
Set-Cookie:JSESSIONID=7809798C607C086C57C65C576C858787
4) 客户端将 Session ID 保存到浏览器Cookie缓存中
5) 当客户端再次向服务器发送请求时,都会使用Cookie携带这个 Session ID ,示例如下:
在客户端的浏览器中,请求报文中可看到如下
Cookie:JSESSIONID=7809798C607C086C57C65C576C858787
6) 服务器端接收到带有 Session ID 的请求时,会校对这个 Session ID ,如果这个 Session ID 存在,服务器可以从 Session 中读取信息,返回给客户端浏览器
7)如果 Session ID 不存在,则跳转到 2)执行
8)当会话终止或过期时,服务器会删除这个 Session 对象
HTTP协议中没有专门提供传递 Session ID 的参数,使用 HTTP 协议传递 Session ID ,有三种方式:基于Cookie、URL重写、隐藏表单域,接下来对折三种方法进行讲解
1.基于Cookie
该方式需要浏览器开启Cookie,服务器创建 Session 后,会议Cookie的形式,通过响应报文把 Session ID 发送给浏览器,Cookie包括如下内容:
- 该 Cookie 的 name 均类似 SESSIONID ,如Tomcat服务器,对于Web应用程序生成的Cookie,其名称就是 JSESSIONID
- 该 Cookie 的 value 为 HttpSession 对象的 ID
- 该 Cookie 的 path 为当前应用路径
首次请求服务器,响应报文中记录 Session ID 的Cookie,如下;
Set-Cookie:JSESSIONID=30F8002489505377E0249B09D; Path=/cookieExample
此时,浏览器保存了客户端与服务器交互的 Session ID ,客户端再次向服务器发送请求时,就会在请求中携带此Cookie,如下:
Cookie:JSESSIONID=30F8002489505377E0249B09D
2. URL重写
由于Cookie可以被人为地禁用,如果浏览器关闭Cookie,服务器依然会产生Session ID,放入响应报文中,虽然服务器会向浏览器发送set - cookie,当时浏览器不会向服务器发送cookie,Session ID将无法正常使用Cookie进行传递
关闭Cookie,浏览器不会保存Cookie信息,再次访问网站时,请求中不会带有包含 Session ID 的Cookie,服务器在请求中未找到 Session ID ,就会创建新的 Session ID 发送给浏览器,以此循环,就无法对 Session(会话) 进行追踪 ,从而导致会话失败
由此,Cookie被禁用后,浏览器仍然需要把 Session ID 传递到服务器,就需要一种新的机制,经常被使用的一种技术叫URL重写,就是把 Session ID 直接添加到URL后面,java的 response 对象提供了 encodeURL 和 encodeRedirectURL 方法,可以对所有请求路径重新编码,包含 Session ID 的新的URL。用户只需要访问这个URL,就可以获取并向服务器发送 Session ID 。
为了在这个交互过程中始终保持会话状态,就必须在客户每个可访问的路径后面都包含这个 Session ID 。
3.隐藏表单域
这是最简单的方式,将 Session ID 写入页面的隐藏文本框中,即使用隐藏域隐藏起来,通过页面的提交,一同将 Session ID 提交给服务器,从而实现 Session ID 的传递,这些连续的请求对于用户来说都是不可见的。
③ Session对象常用方法
1.获得HttpSession对象
request. getSession()无参方法,从request对象中获取Session对象,如果不存在,则创建一个Session对象,该方法的详解如下。
-
如果用户带着一个名称为 JSESSION ID 的Cookie过来了,先按照ID到服务器内存中找出对应的HttpSession对象。
-
未找到或者浏览器没有带,则创建一个新的HttpSession对象,亦即有了新的ID,同时写给客户端 JSESSIONID = sessionid.
-
如果找到了,返回该HttpSession对象,继续为用户服务。
由此可见, getSession ()方法不仅是获取HttpSession对象,也是创建HttpSession 象的方法。
request. getSession(boolean b);有参方法 b 参数的取值为布尔型。如果b为true,作用等同于request. getSession ()无参方法;如果b为false,作用只是获取。若找不到,则返回null,获取Session的示例代码如下:
//从请求中获取Session,如果没有则创建新SessionH
HttpSession session = request.getSession();
//同无参方法
HttpSession session = request. getSession(true);
//从请求中获取Session,如果没有则返回null
HttpSession session = request. getSession(false);
一个常见的误解是以为Session在客户端第一次访同时就被创建,然而事实是只有服务器端程序调用request. getSession (true)这样的语句时, Session才被创建。需要注意的是,果JSP页面没有显示地使用<%@ page session =“false”%>关闭Session,则JSP文件在编成 Servlet 时将会自动加上下面一条语句。
HttpSession session = HttpServletRequest.getSession(true) ;
这也是JSP中隐含的Session对象的来历。由于Session会消耗内存资源,因此,如’'算使用Session,应该在所有的JSP中关闭它。
在JSP中关闭Session后,服务器端不会创建Session,页面代码如下:
<html>...<body><p>在jsp中使用 <%@page session = "false"%> </p><p>关闭 session后,服务器端不会产生sesion. </p><p>直到服务器端使用request.getSession()方法时,才会产生session </p></body >
</html>
2.操作Session属性
-
void setAttribute (String name, Object obj) 方法;向Session中添加属性。属性使用的是name/value对(名/值对)的方式表示。
- name参数是String类型,表示添加到Session中属性的名称, Session对象中的属性名称要必须保证唯一性。
- obj参数是Object类型,表示添加到Session中的数据对象,可以是任意类型的数据。
-
Object getAttribute (string name)方法,从Session中获取指定属性名的数据,返回值为Object类型,在使用过程中,需要根据数据的实际类型进行强制转换。
- name参数是String类型,表示想要获取的Session中属性的名称。
-
void removeAttribute (String name)方法,从Session中移除属性。
- name参数是String类型,表示想要移除的Session中属性的名称。
-
String getld()方法,获取Session ID的值,返回值为字符串。
操纵Session属性的示例代码如下。
//获取Session对象
HttpSession session = request.gelSession();
//向Session中添加名为user的属性,值为bijing
session.setAttribute("user"," bijing");
//从Session中获取名为user的属性的值,返回值为bijing
String user = (String) session.get.Attribute("user");
//从Session中移除名为user的属性
session.removeAttribute("user" );
//从Session中获取Session ID
String sessionID = session.getID();
3.销毁Session
void session. invalidate()方法,立刻摧毁服务器中的HttpSession对象。Session存储在服务器内存中,本身就会消耗服务器资源,因此当Session不再被使用时,就要调用此方法销毁Session.
销毁Session的示例代码如下:
//从服务器上销毁Session
session.invalidate();
调用session. invalidate()方法,会将Session对象从服务器上删除,也就删除了该Session所记录的该用户的所有会话信息。在客户端的后续请求中,依然会携带之前的Session ID,直到服务器使用request. getSession ()获取Session对象。服务器找不到Session ID对应的Session对象时,就会创建新的Session对象,并把Session ID响应给客户端。
4. Session过期
Session过期是指当Session开始后,在一段时间内,用户没有和Web服务器交互,这个Session会话会失效。Session默认的过期时间为30 min, Tomcat会开启一个后台线程每隔段时间检查Session的有效性,并删除过期的Session。
int getMaxlnactivelnterval () ,获取Session过期时间,返回值以秒为单位。
void setMaxInactivelnterval(int interval),设置允许Session保持不活动的时间,也就是Session过期时间。
- interval参数以秒为单位,表示允许不活动的时间。值为零或负数,则表示会话将永远不会超时。
此方法设置的是当前会话的失效时间,不是整个Web的Session过期时间,如果想设置整个Web的Session过期时间为20 min,需要修改web. xml,并增加如下代码。
//设置Session过期时间
<session — config ><session - timeout > 20 </session - timeout >
</session - config >
<session — config >用来指定默认的会话超时时间间隔,以分钟为单位。该元素值必须为整数。如果 session-timeout 元素的值为零或负数,则表示会话将永远不会超时。
当用户第一次访问Web应用中支持Session的某个页面时,就会开始一个新的Session。接下来当用户浏览这个Web应用的不同网页时,始终处于同一个Session中。
Session的作用时间是从创建开始,到Session失效为止。使Session失效的方法有以下3种
-
客户端关闭浏览器(正常关闭)。
-
Session过期。
-
服务器端调用HttpSession的invalidation ()方法。
严格地讲:关闭浏览器删除的是Cookie,服务器端的Session依然存活着,当重新打开一个浏览器时,服务器端会创建一个新的Session ID,从而使原Session 过期后失效。