Javaweb基础(四)Cookie和Session

一.Servlet细节

1.Servlet细节

1):一个Servlet向外暴露多个资源名称(一般来说,一个Servlet使用一个资源名称即可).
方式1:同一个<servlet>元素,提供多个<servlet-mapping>元素.
方式2:在<servlet-mapping>元素中提供多个<url-pattern>元素.

2):Servlet的资源名称使用通配符表示(:表示N个任意字符).

  • 方式1:/:任意的资源名称都可以访问该Servlet.
    推论:/system/
    :访问的资源名称必须以/system/打头才可以访问(在简单权限控制的时候使用).
  • 方式2:*.拓展名: 比如: *.do:凡是以.do结尾的资源名称都可以访问当前的Servlet.

3):自定义的Servlet在编写<servlet-name>元素的时候,文本内容不能叫做:default.
原因是:在Tomcat根/conf/web.xml文件,有一个DefaultServlet的<servlet-name>就叫做:default.
如果我们也起名叫做:default,将会覆盖DefaultServlet的配置.
DefaultServlet的作用是:在于访问静态的资源(html/图片/css/js等).

web.xml.png

4):默认情况下,Servlet的创建时机,在第一次访问Servlet的时候,创建Servlet对象并调用init方法做初始化操作:
如果我们的某一个Servlet是用来做初始化操作的(比较耗时),那么也将会在第一次请求的时候才会执行,第一用户耗时比较长.
解决方案:在系统(Tomcat)启动的时候,就对初始化Servlet做创建以及初始化操作,启动耗时延迟.
在<servlet>元素中配置: <load-on-startup>数字</load-on-startup>.数字越小越优先加载.

2.Servlet3.0新特性-注解配置

1.说明
从JavaEE6(Tomcat7,Servelt3.0)开始,可以使用(WebServlet)注解来取代传统的XML配置.
所以我们说,从Tomcat7开始,web.xml文件不再是必须的,但是我们一般都保留该文件.

注意:web.xml文件中的:metadata-complete="true",表示是否忽略扫描Servlet上的注解标签.

metadata-complete.png
metadata-complete="true" :要忽略扫描注解.
metadata-complete="false":不忽略,要扫描注解.(不写该属性,缺省就是false.)

2.Servlet的注解使用方式

Servlet的注解使用方式.png

使用WebServlet的注意:
1): metadata-complete="false"或者删除该属性:
2): @WebServlet("/资源名"),资源名称必须使用/打头.

3.注解和XML的使用对比

Paste_Image.png

4.如何选择使用
开发中到底使用XML配置还是注解配置:

  • XML配置:

    • 优点:直观,清晰,可以统一配置,维护性较高.
    • 缺点:繁琐,如果配置信息比较多,配置文件会臃肿.
  • 注解配置:

    • 优点:简单,高效.
    • 缺点:配置不够清晰,不能统一管理,硬编码又再次回到了Java代码中.

在开发中因情况而定.
一般说来,我们使用XML做统一通用的配置,个别的配置可以使用注解来完成.

3.安全问题

多线程并发访问同一个资源,会造成线程不安全问题.
Servlet是单例的,Servlet中的成员变量name,也就只有一个空间,后来的数据会覆盖name空间的之前的数据,
解决方案:

  • 方式1:让Servlet实现SingleThreadModel(过时).只允许一个线程访问当前Servlet,但是效率很低.
  • 方式2:在Servlet中不要使用成员变量,使用局部变量.
    在service方法中定义的局部变量,每一个线程发出请求的时候,都会重新调用service方法.
Servlet安全问题.png

4.Servlet总结

Servlet:其实就是一个特殊的类,继承于HttpServlet.
作用:

  • 1):输出一个动态网页.
  • 2):处理用户的请求.

Servlet的优缺点:

  • 优点: 是动态网页,跨平台, Servlet是单实例的,在Tomcat中一个Servlet就只有一个对象-->效率比较高.
  • 缺点: 输出动态网页太恶心(JSP). Servlet的单实例提高了效率,但是却带来了安全性问题.

二.Http协议无状态带来的问题

1.HTTP协议:

规范了浏览器和服务器之间传输数据的格式.
Http协议是无状态的:(健忘的人).服务器不知道上一次请求是哪一个客户端发出的.

HTTP是无状态协议,也就是没有记忆力,每个请求之间无法共享数据。这就无法知道会话什么时候开始,什么时候结束,也无法确定发出请求的用户身份。

2.会话:

百度百科的解释:简单为,打开浏览器,访问一个站点,在这一个网站中和服务端有多次交互,最后关闭浏览器,整个过程就称之为一次会话.
在这一次会话中,用户需要和服务端做多次交互,每一次交互都是一个(请求-响应),HTTP协议是无状态的,服务端怎么怎么你的这一次请求和上一次请求是同一个用户发出的.
在一个会话中共享多次请求的数据即会话跟踪技术.

登录邮件系统:收邮件:

邮件系统流程分析:


邮件系统流程分析.png

3.解决的问题:如何跟踪用户的会话信息(处理多个请求之间共享数据).**

方式1:在资源后面使用传递参数的机制.
比如: /param/list?username=iwiller .
那么在ListServlet就可以通过request.getParameter获取参数.
该方式很不安全,因为超链接的请求参数会全部暴露在浏览器的地址栏.http://localhost/param/get?username=will
解决方案:
传递参数的时候,不要把参数存放在请求的行里面(浏览器地址栏),
最好把请求参数,存放于请求头中,如此一来浏览器中看不到,比较安全.--->Cookie.

方式2:Cookie.

方式3:Session.

三.Cookie

1.什么是Cookie:

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

客户端技术:多个请求时需要共享数据,我们把共享数据存放于客户端(浏览器)中.
原理(办会员卡的例子):

办会员卡的例子.png

使用Cookie和不使用Cookie的区别(请求/响应中)

使用Cookie和不使用Cookie的区别.png

2.Cookie的操作:

保持cookie.png

1:创建Cookie对象并设置共享数据[办一张会员卡,并填写卡上的信息].

  Cookie  c = new Cookie(String name,String value);
  Cookie c = new Cookie("currentName","Will");
     参数:
      name:  给共享数据起个名字
      value: 多个请求之前需要共享的数据

2.把Cookie放入响应中,响应给浏览器(把会员卡交给客户).
response对象.addCookie(c);
3.从请求中获取Cookie对象,再从Cookie中获取共享的数据(客户带卡去健身房).

  Cookie[] cs = req.getCookies();

4.:Cookie的属性名和属性值都不支持中文.
解决方案:URLEncoder对中文做编码操作.

  • 编码(放进Cookie之前):
    Cookie  cookie = new Cookie("currentName",URLEncoder.encode(username, "UTF-8"));
  • 解码(从Cookie中获取出来):
   username = URLDecoder.decode(c.getValue(), "UTF-8");

5.修改Cookie(修改Cookie中存放的共享数据).

  • 方式1:获取被修改的Cookie对象,cookie对象.setValue(新的数据)(不推荐);
  • 方式2:创建一个和被修改Cookie同名的Cookie对象,只改变value值即可.
    Cookie xxx = new Cookie("currentName","lucy");
    注意:此时修改重新把修改之后的Cookie响应给浏览器.

6.Cookie的分类(根据Cookie存活的时间,分成两大类).

名称 解释
会 话Cookie: 在当前会话中有效,浏览器关闭就销毁了.此时该Cookie存放在浏览器进程中(缺省).
持久化Cookie: 可以存活指定的时间(我们需要来设置Cookie的存活时间).

Cookie对象.setMaxAge(int seconds);设置Cookie对象存储的最大时间.

7.删除Cookie.
Cookie对象.setMaxAge(0):表示立刻删除该Cookie对象.

8.设置访问路径和域.
Cookie的path是在同一主机中指定共享Cookie,如果主机不同那么就一定不能共享Cookie,无论path是什么。
需求:AServlet和BServlet共享Cookie:

  • 如果:AServlet的资源路径是/cookie/a,BServlet的资源路径是:/cookie/b. 此时共享成功.
  • 如果:AServlet的资源路径是/cookie/a,BServlet的资源路径是:/ooxx/b. 此时不能共享.

(1)默认情况下会根据Servlet的相对路径来做判断.
若需要让整个应用中所有的Servlet都可以获取该Cookie,则设置为:Cookie对象.setPath("/");

(2)如果希望不同的二级域名中可以共享Cookie,那么就要设置Cookie的domain了。
例如:music.baidu.com、map.baidu.com、tieba.baidu.com,它们的域名不同,但百度希望它们之间可以共享Cookie,那么就要设置domain了。
1). 设置Cookie的path为“/”,例如:cookie.setPath("/");
2). 设置Cookie的domain,例如:cookie.setDomain(".baidu.com"),其中domain中没有指定域名前缀!
在music.baidu.com主机中的某个项目中保存了Cookie
在map.baidu.com主机中某个项目中获取Cookie

当然这需要配置两个虚拟主机才行。

3.Cookie的缺陷:

1):Cookie存储中文的时候,操作麻烦(手动的编码/解码操作);
2):Cookie存储在浏览器中,多个人使用共同的一台的电脑的时候,不安全.
3):Cookie的文件大小和数量是有限制的.

  • Cookie大小限制在4KB之内;
  • 一台服务器在一个客户端最多保存20个Cookie;
  • 一个浏览器最多可以保存300个Cookie;

4):Cookie的value只能存储String类型的数据,一个Cookie只能存储一个共享数据.
若需要共享多个数据,就得创建多个Cookie对象.--->操作麻烦
如果Cookie的Value可以存储Object类型,我们就可以把多个数据封装成对象,再做存储.

5):Cookie在设计上的问题.
Cookie的设计:把客户端和服务端的识别数据存放于客户端中,这个在设计上有点不合理.
最好的设计方式:把识别数据存放于服务端,客户端只需要存储一个标志即可.
新会员过来, 把新会员的数据录入到系统中(健身房这里/服务端).
下一次,会员来健身,只要报手机号码,就可以从系统中找到该用户的识别数据.---->Session.

四.Session

1.什么是session

Session其实就是一个特殊的会话Cookie,浏览器关闭Session就销毁了.

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

cookie的方式

cookie的方式.png

session的方式

session的方式.png

session对象

session对象.png

session和cookie的区别

session和cookie的区别.png

2.操作Session:

1.创建和获取Session对象.

// 如果当前存在Session对象,则直接返回,如果当前没有Session对象,先创建一个Session对象,再返回.
   HttpSession session  = request对象.getSession(true); 
// 如果当前存在Session对象,则直接返回,如果没有,在则返回null.
   HttpSession session  = request对象.getSession(false); 
//等价于 request对象.getSession(true).
   HttpSession session  = request对象.getSession();

2.往Session中存储共享数据.
session对象.setAttribute(String name,Object value);

  • 0):一般的,我们把存储在session中的属性起名为:XXX_IN_SESSION.
  • 1):因为Session的setAttribute方法支持Object类型,所以我们可以把多个共享数据封装成对象,再存储到session中.
    session.setAttribute("USER_IN_SESSION",user对象);
  • 2):一般的,为了多态服务器之间共享session中的数据,我们把session中的对象实现java.io.Serializable接口.
    当某一个对象只有实现java.io.Serializable接口之后,才可以做序列化操作.

序 列化: 把对象的数据以二进制的形式存储到文件中.------>网络传输.
反序列化: 把二进制形式的数据恢复成Java对象.

3.获取Session中存储的数据.
Object value = session对象.getAttribute(String name);

4.删除Session(删除Session中存储的共享数据)[登录注销]:

  • 方式1:session对象.remove(String name);从当前session中删除指定属性名的属性.
  • 方式2:session.invalidate();销毁session对象,从而session中的数据全部没了.

5.Session的超时管理.
超时时间:用户的两次操作的最大间隔时间:超时时间到了,就会销毁Session.
session对象.setMaxInactiveInterval(int seconds):
一般说来:不用设置,Tomcat中默认为30分钟.

6.URL重写.
Session其实也就是一个会话Cookie(浏览器关闭之后,浏览器存储的jsessionid消失了,session对象在服务端依然存在).
浏览器可以禁用Cookie(不接受Cookie),非常不推荐的,操作相当麻烦.

解决方案:手动的在每一个资源后面携带:;jsessionid= session的id值.
http://localhost/session/get ------>因为浏览器没有存储session的id值,所以找不到服务端的共享数据内存地址.
http://localhost/session/get;jsessionid=FACF8BD9AFB39C1A85A1B1FDC1978923 .
URL重写:
String newUrl = response对象.encodeURL(String oldUrl);
String newUrl = response对象.encodeURL("session/get");返回:/session/get;jsessionid=FACF8BD9AFB39C1A85A1B1FDC1978923

五.总结

解决用户的会话跟踪问题(实现多个请求之间共享数据):
Cookie: 客户端技术:把共享数据存储在浏览器中.
Session:服务端技术:把共享数据存储在服务端,只是给了客户端一个地址(jesseionid).


电子商城的购物车:
1):session来做:浏览器关闭,购物车中的数据也就消失了.
2):如果没有登录: 此时把购物车中的商品信息存储到cookie中.
3):一旦登录,先读取该站点的Cookie,把商品信息持久化到数据库.


Cookie的应用:
1):记住多久不用登录.
2):购物车
3):存储网站的个人爱好设置.
4):单点登录(针对多个应用).

Session的应用:
1):登录信息存储到session中.
2):网站需要统计在线会员人数.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,311评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,339评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,671评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,252评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,253评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,031评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,340评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,973评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,466评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,937评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,039评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,701评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,254评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,259评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,485评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,497评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,786评论 2 345

推荐阅读更多精彩内容