cookie

来源:互联网 发布:卡尔顿乳酪面包淘宝 编辑:程序博客网 时间:2024/05/23 14:52

二.会话技术

会话的介绍:

会话可简单理解为:用户开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭浏览器,整个过程称之为一个会话

会话的作用:

每个用户与服务器进行交互的过程中,各自会有一些数据,程序要想办法保存每个用户的数据。

例如:用户点击超链接通过一个servlet购买了一个商品,程序应该保存用户购买的商品,以便于用户点结帐servlet时,结帐servlet可以得到用户商品为用户结帐

 

会话技术会为两类

Cookie

Cookie是客户端技术,程序把每个用户的数据以cookie的形式写给用户各自的浏览器。当用户使用浏览器再去访问服务器中的web资源时,就会带着各自的数据去。这样,web资源处理的就是用户各自的数据了。

 

Session

Session是服务器端技术,利用这个技术,服务器在运行时可以为每一个用户的浏览器创建一个其独享的session对象,由于session为用户浏览器独享,所以用户在访问服务器的web资源时,可以把各自的数据放在各自的session中,当用户再去访问服务器中的其它web资源时,其它web资源再从用户各自的session中取出数据为用户服务。

.cookie

1. cookie的介绍

Ø 什么是cookie

Cookie最早是网景公司的前雇员Lou Montulli19933月的发明。

Cookie是由服务器端生成,发送给User-Agent(一般是浏览器),浏览器会将Cookiekey/value保存到某个目录下的文本文件内,下次请求同一网站时就发送该Cookie给服务器(前提是浏览器设置为启用cookie)。Cookie名称和值可以由服务器端开发自己定义,对于JSP而言也可以直接写入jsessionid,这样服务器可以知道该用户是否合法用户以及是否需要重新登录等,服务器可以设置或读取Cookies中包含信息,借此维护用户跟服务器会话中的状态。

Ø cookiehttp

u cookiehttp协议关系

CookieHttp协议制定的,并不是Java语言独有的,PHT.NET中也使用了cookie技术,因此只要是和HTTP协议相关,那么就可以使用cookie技术。

我们知道cookie是服务器创建的一个键值对,并保存在浏览器端。那么服务器是如何将cookie发送给浏览器的呢?

在服务器端先创建cookie,如Cookie cookie=new Cookie(String name,String value),其中Cookie可以在javaeeAPI中查到的,详情可参考java_ee API。然后再通过response对象将cookie信息作为响应头发送到浏览器端。我们可以通过HttpWatch抓包工具查看响应信息,可以发现cookie是基于一个Set-Cookie响应头工作的,由于Set-Cookie响应头可以有多个,所以我们可以通过response.addHeader(String name,String value)方法发送Set-Cookie响应头,例如,有两个cookie,分别为one=aaatwo=bbb,其中onetwocookie的名称,aaabbbcookie的值。发送响应头如下所示:

response.addHeader(Set-Cookie,one=aaa)

response.addHeader(Set-Cookie,two=bbb)

当浏览器再次访问服务器时,会将cookie送还给服务器。那么浏览器是如何将cookie带给服务器的呢?其实通过Cookie请求头传递过去的。请求头Cookie与响应头Set-Cookie有区别,多个cookie对应多个Set-Cookie响应头,但是只对应一个Cookie请求头,格式为:Cookieone=aaatwo=bbb。即多个cookie之间用分号和空格隔开。

需要注意的是:cookie是不能跨浏览器的。例如,张三首先使用IE浏览器访问服务器,服务器发送了一个cookie,这个cookie只会保存在IE浏览器,如果再使用火狐浏览器访问服务器,服务器会再发送一个cookie个火狐浏览器,在火狐浏览器中不能获取IE浏览器中的cookie,同理IE浏览器也获取不到火狐浏览器中的cookie

u http协议规定

Http协议对Cookie做了一些规定,如下所示:

a. 一个Cookie的大小,最大为4KB

b. 一个服务器最多向一个浏览器保存20Cookie

c. 一个浏览器最多可以保存300Cookie

我们知道,浏览器将服务器发送过来的cookie保存在本地磁盘,如果cookie过多,必然会加大浏览器的压力,因此Http协议对Cookie做了以上规定。

但是,目前浏览器之间因为竞争,很多都在一定范围内违反了Http规定,例如,一个浏览器最多保存的Cookie个数超过300个。但是也不会出现浏览器允许一个Cookie的大小超过4GB

 

2. cookie常用api及其原理

javax.servlet.http.Cookie类用于创建一个Cookieresponse接口也中定义了一个addCookie方法,它用于在其响应头中增加一个相应的Set-Cookie头字段。 同样,request接口中也定义了一个getCookies方法,它用于获取客户端提交的Cookie

u 构造方法

Øpublic Cookie(String name, String value):构造带指定名称和值的cookie

u 成员方法

Øpublic String getName():返回cookie的名称

Øpublic String getValue():返回cookie的值。

Øpublic void setMaxAge(int expiry):设置cookie的最大生存时间,以秒为单位,清空浏览器的缓存,设置为0,则为删除cookie(前提是保持路径一致)

Øpublic void setPath(String uri):指定客户端应该返回cookie的路径。

接下来,咱们来做个案例看下cookie是如何使用的.

day10工程下创建一个CookieDemo1Servlet,写入以下代码:

//1.创建cookie

Cookie cookie=new Cookie("cookieName","cookieValue");

//2.通过response对象将cookie响应到浏览器

response.addCookie(cookie);

 

然后通过抓包工具看下:

当在浏览器上访问http://localhost/day10/cookieDemo1,抓取到的http请求与响应信息如下:

请求信息:

GET /day10/cookieDemo1 HTTP/1.1

Accept: text/html, application/xhtml+xml, */*

Accept-Language: zh-CN

User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)

Accept-Encoding: gzip, deflate

Host: localhost

Connection: Keep-Alive

 

响应信息

HTTP/1.1 200 OK

Server: Apache-Coyote/1.1

Set-Cookie: cookieName=cookieValue

Content-Length: 0

Date: Tue, 12 May 2015 05:26:53 GMT

 

再次访问此页面

请求信息:

GET /day10/cookieDemo1 HTTP/1.1

Accept: text/html, application/xhtml+xml, */*

Accept-Language: zh-CN

User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)

Accept-Encoding: gzip, deflate

Host: localhost

Connection: Keep-Alive

Cookie: cookieName=cookieValue

 

通过以上分析,我们通过下面图进行总结:
















  

 

 

 

3. cookie的持久化

Ø 持久化

如果创建了一个cookie,并将他发送到浏览器,默认情况下它是一个会话级别的cookie(即存储在浏览器的内存中),用户退出浏览器之后即被删除。若希望浏览器将该cookie存储在磁盘上,则需要使用Cookie类的setMaxAge方法,并给出一个以秒为单位的时间。

0代表的是删除持久cookie,注意,删除cookie时,path必须一致,否则不会删除

-1代表的是浏览器关闭后失效.

Ø 路径:

Cookie的路径是在服务器创建Cookie时设置的,它的作用是决定浏览器访问服务器的某个资源时,需要将浏览器端保存的那些Cookie归还给服务器,可以通过Cookie类的setPath方法来设置cookie的路径.

关于路径包含关系

例如,浏览器中保存如下几个cookie,它们的路径分别是:

aCookie.path=/day10/

bCookie.path=/day10/jsps/

cCookie.path=/day10/jsps/cookie/

访问路径是:http://localhost:8080/day10/index.jsp

浏览器发送给服务器的cookie有:aCookie

访问路径是:http://localhost:8080/day10/jsps/a.jsp

浏览器发送给服务器的cookie有:aCookiebCookie

访问路径是:http://localhost:8080/day10/jsps/cookie/b.jsp

浏览器发送给服务器的cookie有:aCookiebCookiecCookie

4. 案例--记录上次访问时间

Ø 功能描述

当访问day10工程下的某一个servlet时,会显示出上一次访问这个资源的时间。

Ø 案例分析

 

 

Ø使用到的知识点分析

n Cookie cookie=new Cookie(); 创建cookie

n response.addCookie()  cookie添加到http响应中

request.getCookies();  获取所有的cookie

 

Ø 代码实现

VisitServlet

public class VisitServlet extends HttpServlet {

 

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

 

doPost(request, response);

}

 

public void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

//1.得到系统当前时间

Date date=new Date();

//2.创建一个cookie

Cookie cookie=new Cookie("time",date.getTime()+"");

//3.cookie通过response响应到浏览器端

response.addCookie(cookie);

}

}

 

ShowTimeServlet

public class ShowTimeServlet extends HttpServlet {

 

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

 

doPost(request, response);

}

 

public void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

//设置响应编码

response.setContentType("text/html;charset=utf-8");

//1.得到名称叫timecookie

Cookie[] cs = request.getCookies();

//2.遍历cs,得到cookie

for(Cookie c:cs){

if("time".equals(c.getName())){//判断cookie的名称是否有叫time

long time=Long.parseLong(c.getValue()); //得到名称叫timecookievalue

Date date=new Date(time); //构造出新的时间

response.getWriter().write(date.toLocaleString());

return;

}

}

response.getWriter().write("第一次访问:"+new Date().toLocaleString());

}

}

 

上面的代码已经实现了我们的需求,但是不妥的地方是还得需要单独访问一下才知道上次的时间.我们完全可以把两个合二为一

public class ShowCurrentTimeServlet extends HttpServlet {

 

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

 

doPost(request, response);

}

 

public void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

// 1.设置响应编码

response.setContentType("text/html;charset=utf-8");

 

// 2.获取一个名称叫timecookie.

Cookie cookie = findCookieByName("time", request.getCookies());

Date now = new Date();

if (cookie == null) {

// 说明第一次访问

response.getWriter().write("第一次访问时间是:" + now.toLocaleString());

} else {

// 不是第一次访问

long time = Long.parseLong(cookie.getValue());

response.getWriter().write("上次访问时间是:" + new Date(time).toLocaleString());

}

 

// 需要将这时访问的时间存储到cookie中。

cookie = new Cookie("time", now.getTime() + "");

//持久化cookie

//cookie.setMaxAge(60*60*24*7);

cookie.setMaxAge(0);//删除cookie

response.addCookie(cookie);

 

}

 

// 根据名称查找cookie

private Cookie findCookieByName(String name, Cookie[] cs) {

if (cs == null || cs.length == 0) {

return null;

}

for (Cookie c : cs) {

if (name.equals(c.getName())) {

return c;

}

}

return null;

}

}

 

 

 

5. 案例--查看历史记录

Ø 功能描述

做一个商品页面,当我们访问后,在页面上点击查看商品浏览记录后,可以查看到以前浏览过的商品信息

Ø 案例分析

 

 

Ø使用到的知识点分析

超连接带参数  <a href=/day10/book?id=1>

获取请求参数  request.getParameter()

创建Cookie cookie=new Cookie()

获取所有cookie   request.getCookies()

cookie响应到浏览器端   response.addCookies()

 

 

 

Ø 代码实现

book.jsp

<a href="/day10/book?id=1">西游记</a><br>

<a href="/day10/book?id=2">水浒传</a><br>

<a href="/day10/book?id=3">红楼梦</a><br>

<a href="/day10/book?id=4">三国演义</a><br>

<hr>

<a href="/day10/bookHistory.jsp">查看浏览商品记录</a>

 

BookServlet

public class BookServlet extends HttpServlet {

 

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

 

doPost(request, response);

}

 

public void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

response.setContentType("text/html;charset=utf-8");

// 1.得到商品的id

String id = request.getParameter("id");

 

// 2.id值保存到cookie的名称叫ids这个cookie中。

Cookie cookie = CookieUtils.findCookieByName("ids",

request.getCookies());

 

if (cookie == null) { // 第一次没有ids,就得到null

cookie = new Cookie("ids", id);

} else { // 不是第一次,就得到的不是null.

// 3.得到cookievalue值。

String ids = cookie.getValue();

 

// 判断id是否重复

List<String> list = Arrays.asList(ids.split("-")); //将数组转换成集合。

 

if (!list.contains(id)) {

ids = ids + "-" + id;

}

cookie = new Cookie("ids", ids);

 

}

 

response.addCookie(cookie);

response.getWriter().write("商品展示成功,<a href='/day10/book.jsp'>继续浏览</a>");

}

}

 

bookHistory.jsp

<%

String[] books = { "西游记", "水浒传", "红楼梦", "三国演义" };

 

//1.得到所有的cookie,得到名称叫idscookie

Cookie[] cs = request.getCookies();

Cookie c = CookieUtils.findCookieByName("ids", cs);

 

if (c == null) {

//没有浏览记录

out.print("无浏览记录");

} else {

//有浏览记录

//2.得到cookievalue

out.print("浏览记录如下:<br>");

String ids = c.getValue(); //1-2-4

 

String[] id = ids.split("-");

 

for (int i = 0; i < id.length; i++) {

int bookid = Integer.parseInt(id[i]) - 1;

out.print(books[bookid] + "<br>");

}

 

}

%>

原创粉丝点击