会话跟踪技术

会话跟踪技术

在 JavaWeb 项目中浏览器向服务器发送第一个请求开始,会话就已经开始了,直到浏览器关闭,会话结束;

会话跟踪技术就是:在一个会话中的多个请求中共享数据.

1.CooKie技术

Http的协议是无状态协议,也就是每个请求都是独立的,不记录前一次请求的状态,所以在Http协议中可以使用Cookie技术来完成会话跟踪

Cookie是一个键和一个值组成,随着服务器的响应发送给浏览器.然后浏览器将CooKie保存起来,当下一次再访问服务器时把CooKie再发送给服务器

CooKie是不能跨浏览器的

CooKie中不能存在中文

CooKie的用途:

1.服务器使用CooKie来跟踪客户端状态

2.保存购物车信息

3.显示上次登录名

...

CooKie与HTTP头

CooKie是通过HTTP的请求和响应头在客户端和服务器端传递的

CooKie:

    请求头,客户端发送给服务器端

    格式:CooKie:a=A;b=B;c=C //多个CooKie用分号隔开

Set-Cookie:

    响应头,服务器端发送给客户端

    一个CooKie对象一个Set-Cookie:

        Set-CooKie:a=A

        Set-Cookie:b=B

        Set-Cookie:c=C

CooKie覆盖

如果服务器端发送重复的CooKie,那么会覆盖原本的CooKie.

JavaWeb中使用Cookie

原始做法:

使用response发送Set-Cookie响应头

使用request获取CooKie请求头

便捷方法:

使用response.addCooKie()方法向浏览器保存CooKie

使用request.getCooKies()方法获取浏览器返还的Cookie

例子1:

一个jsp保存cookie  a.jsp

一个jsp获取浏览器归还的cookie b.jsp

//a.jsp

<html>

<head>

<title>保存Cookie</title>

</head>

<body>

<%

Cookiecookie1=newCookie("aaa","AAA");

response.addCookie(cookie1);

Cookiecookie2=newCookie("bbb","BBB");

response.addCookie(cookie2);

%>

</body>

</html>


//b.jsp

<html>

<head>

<title>获取Cookie</title>

</head>

<body>

<%

Cookie[]cookies=request.getCookies();

if(cookies!=null) {

for(Cookiec:cookies) {

out.print(c.getName()+"="+c.getValue()+"<br/>");

       }

   }

%>

</body>

</html>

例子2:

        //把数据传给CooKie

Cookiecookie=newCookie("username",username);

//把数据写回浏览器

resp.addCookie(cookie);

Stringusername=null;

//获取浏览器带过来的数据

Cookie[]cookies=req.getCookies();

for(Cookiecookie:cookies) {

if("username".equals(cookie)) {

username=cookie.getValue();

           }

       }

欢迎: ${cookie.username.value}<br>

使用${cookie.username.value} 可以不用在servlet再获取username的值;节省了数以万计的代码,更简洁

但是因为传递机制的问题,在登录后的第一个页面,使用这种方法会找不到cookie.username.value 值的问题,只能从servlet中req.setAribute("username",username) 进行获取

修改cookie

有两种方式:

1> 修改指定Cookie的值

Stringusername=null;

Cookie[]cookies=req.getCookie();

for(Cookiecs:cookies){

Stringname=cs.getName();

if("username".equals(name)){

username=cs.getValue();

cs.setValue("xiaoming");

resp.addCookie(cookie);

req.Attribute("username",username);

   }

}

2> 新建Cookie用来覆盖原先的Cookie

Cookiecookie=newCookie("username","xiaoming");

resp.addCookie(cookie);

设置Cookie的存活时间

Cookie对象的 setMaxAge(int expiry)

setMaxAge(60);  设置存活时间 60 秒  单位为秒

setMaxAge(0); 设置为立即消除当前Cookie对象

setMaxAge(-1); 会话Cookie 浏览器关闭即销毁

Cookie存在浏览器中,默认情况下都为会话Cookie 浏览器关闭即消除

按照分类可分为持久性Cookie 和 非持久性Cookie

持久性Cookie存在磁盘中,只有用户手动消除或者到期才被删除

非持久性Cookie存在内存中,浏览器关闭就消失,存在时间短暂

//创建Cookie的时候设置存活时间

Cookiecookie=newCookie("username",username);

cookie.setMaxAge(60);//设置无操作60秒后自动销毁Cookie对象

cookie.serMaxAge(0);//设置立即销毁当前Cookie对象

cookie.setMaxAge(-1);//设置会话Cookie 浏览器关闭即销毁

resp.addCookie(cookie);

删除Cookie

设置setMaxAge(0)即可

Stringusername=null;

Cookie[]cookies=req.getCookie();

for(Cookiecs:cookies){

if("username".equals(cs.getName())){

cs.setMaxAge(0);

    resp.addCookie(cs);

break;

   }

}

cookie的中文问题

在TomCet8.5以下的Cookie中 name属性和value属性都不支持中文,如果有中文必报500状态

在TomCet8.5以后的版本则不需要手动解决;

TomCet8.5以下 中文解决思路:

URLEncoder类 encode("中文","UTF-8");方法  把中文字符转换为非中文

URLDecoder类 decode("非中文","UTF-8"); 方法 把非中文转化为中文

//往Cookie中存中文

Cookiecookie=Cookie("小明",URLEncode.encode("UTF-8"));

//获取Cookie中的中文

Cookie[]cookies=req.getCookies();

for(Cookiecs:cookies){

if("useranem".equles(cs.getName)){

URLDecode.decode(cs.getValue(),"UTF-8");

   }

}

Cookie 域/路径

1.作用

为了浏览器能够识别Cookie发送到对应的服务器,以及识别哪些请求要携带Cookie,默认Cookie都带了服务器的标识以及需要携带Cookie的资源标识,这是出于安全的考虑,为了保护Cookie不被带到别的服务器里去

2.

用来识别服务器,包含IP : 端口或域名:端口 , 可通过Cookie对象的setDomian方法设置.

默认的Cookie中的域是创建Cookie的服务器的域名.域名分类:

1.一级域名: (比如)  baidu.com

2.二级域名: (比如)  map.baidu.com

3......

若想在相同的主域名中共享Cookie资源,之需要设置Cookie的domain即可,若主域名不同则无法共享资源

cookie.setDomain(".baidu.com");

3.路径

用来识别资源,可通过Cookie对象的setPath设置,默认是创建Cookie的资源的路径

(比如:)  /cookie/index   则Path则为/cookie,访问带cookie开头的资源都会携带该Cookie

如果想在使用的页面都带上Cookie 设置setPath为"/" 即可 此时/下的页面都会携带该Cookie资源

总结:

若主域不同,不管Path如何都不会共享cookie资源

若主域相同,且path为"/" 则访问该域下的任意资源都会携带该域的Cookie

Cookie问题和应用场景

应用场景:

存用户的标识,解决无状态问题

登录时记住名字

未登录时实现购物车

存在的问题:

1.单独使用的电脑没什么问题,如果是公用的电脑则存在安全问题

2.存数据TomCet8.5以内的比较麻烦,(编码,解码)

3.一个Cookie只能设置一个值,值须字符串类型

4.一台服务器的在一个客户端存储的Cookie大小,数量有限

Cookie大小限制在4K

同一个服务器只能在客户端最多只能存20个cookie

一个浏览器最多只能存300个cookie

2.Session

Session 是服务器端会话跟踪技术,利用这个技术,服务器在运行时可以为每一个用户的浏览器创建一个其独享的Session对象

Session对象由服务器端创建

Session存在服务器中

Session对象在用户第一次访问服务器端资源时创建

Session对象中数据的传递 浏览器 -> 服务器(Session) -> 数据在服务器

服务器如何识别不同的Session?

浏览器 -> 服务器(Session) sessionId

浏览器sessionId -> 服务器

Session其底层依然需要依赖Cookie来传递sessionId ,存sessionId的Cookie为会话Cookie

因此Session在浏览器关闭后就无法进行使用了,原因是sessionId丢失,服务器将会在30分钟后销毁所有未有操作的Session对象

Session的基本API

1.获取Session

HttpSeervletRequest 的API

getSession(true)    判断是否存在Session ,存在则获取,不存在则创建新的Session对象返回

getSession(false)  判断是否存在Session,存在则获取,不存在则返回null

getSession() 判断是否存在Session(浏览器是否携带sessionId),存在则取出,不存在则创建新的Session对象

推荐使用getSession() 满足需求的同时 简洁

2.Session数据共享

HttpSession  的 API:

setAttribute(String name,Object  value)  设置属性名和属性值

getAttribute(String name)  通过属性名获取属性值

removeAttribute(String name)  从Session中移除指定的属性名和属性值

invalidate()  移除整个Session对象 删除所有的属性和属性值

往Session中存入数据

Stringusername=req.getParameter("username");

HttpSessionsession=req.getSession();

session.setAttribute("USER_IN_SESSION",username);

获取Session的数据

Stringusername=null;

HttpSessionsession=req.getSession();

username=(username)session.getAttribute("USER_IN_SESSION");

req.setAttribute("username",username);

因为Session运行在服务器端 , jsp也运行在服务器端,所以jsp中可以直接获取

username = ${USER_IN_SESSION}

移除Session中的元素

//获取Session

HttpSessionsession=req.getSession("USER_IN_SESSION");

//移除Session中指定元素

session.removeAttribute("USER_IN_SESSION");

销毁整个Session

//获取Session

HttpSessionsession=req.getSession("USER_IN_SESSION");

//销毁整个Session

session.invalidate();

Session细节使用

Session超时管理

  设置会话的有效时间

全局修改:

在TomCet的web.xml中的

设置保存多少分钟

局部修改:

在创建Session的servlet中设置

session.setMaxInactiveInterval( 3 );  // 设置只保存 3 分钟

Session的使用规范

一般设置为 XXX_IN_SESSION 且这个属性名是唯一的

session.setAttribute("XXX_IN_SESSION",值);

session中可以存放多个数据,若数据是有联系的,比如用户名和密码, 我们会分装成一个对象再存到Session中

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容