Cookie,Session解决用户的会话跟踪问题

一:Servlet细节
01.Servlet的映射细节

1):一个Servlet程序(WEB组件),可以配置多个<utl-patternt>,表示一个Servlet有多个资源名称

2):一个Servlet程序,可以配置多个<servlet-mapping>.

3):<rul-patternt>必须保证唯一性,而且必须使用/打头.

4):Servlet的映射支持通配符映射( * :表示任意字符);
	
	 第一种:  /*,任意的资源都可以访问该Servlet. /system/*:请求的资源必须以/system/打头才可以访问,Servlet中,权限控制:

   	 第二种:  *.拓展名.比如: *.do,请求的资源必须以.do作为结尾才可以访问该Servlet.

5):在映射Servlet的时候,<servlet-name>元素的文本内容不能是default.

	因为的tomcat中存在一个叫做default的Servlet,专门用于处理请求静态资源(html,css,js,图片等).在Tomcat根/conf/web.xml文件:

6):localhost会默认访问URL为localhost/index.html的静态页面,所以只需要设置web.xml文件中的文件即可:

	<welcome-file-list>
	      <welcome-file>hello.html</welcome-file>
	</welcome-file-list>*/

02.Servlet3.0新特性–注解配置

问题:如果Servlet有N,就得配置10*N行代码,web.xml文件,臃肿,不利于维护,开发效率低,从Tomcat7开始,可以使用注解(WebServlet)来取代XML配置.

使用注意:在Web.xml文件的根元素中,存在属性,表示是否忽略扫描WEB组件注解:

		metadata-complete="true" :  要忽略
	
		metadata-complete="false"   不忽略

		不要改属性:   缺省情况等价于metadata-complete="false" 
		
Servlet代码:

@WebServlet(value="/m1",loadOnStartup=1,
		initParams=
		{@WebInitParam(name="encoding",value="UTF-8"),
		 @WebInitParam(name="name",value="miao")
				}
)

使用配置,可以使用XML文件也可以使用注解:问题XML和注解各自的优缺点是什么,怎么选择?

XML:优点:XML配置很清晰,很直观,因为和JAVA代码相分离,维护性较高.
	
	缺点:XML配置导致配置文件臃肿,开发效率较低.

注解:优点:开发效率高,配置文件不臃肿,也方便快速定位.

	 缺点:和java代码耦在一起,维护性较低.

抉择:一般的在企业中,现在注解使用的非常之多,而我们做开发,XML文件用于做通用配置.个别配置使用注解来.

学习阶段:先学XML配置,再讲注解配置.

03.服务器启动就初始化Servlet

回顾Servlet生命周期方法的执行流程:

	在启动Tomcat服务器的时候,没有Servlet创建和初始化操作.

	在第一次服务端请求的时候:
		
		1):创建Servelt对象.
	
		2):调用init方法做初始化.

		3):调用servlet方法,处理请求.
		
如果某一天,某一个Servlet(核心Servlet:初始化全局信息)需要在启动服务器的时候就创建出来,怎么办

	web.xml中的<servlet></servlet>的配置信息添加:
	
		//在启动服务器的时候就加载,值越小越优先加载//
  		<load-on-startup>1</load-on-startup>

此时该Servlet,会在服务器启动的时候,创建好对象,并做好初始化操作.

使用注解:上面的注解有说到.

比如:在Strutst中的核心Action其本质就是Servlet,既然核心的Action是用来处理所有请求的,
	
	 就应该在服务器启动的时候,就初始化,而不是第一个请求过来,才初始化

04.Servlet线程不安全问题

	造成的根本原因是:Servlet是单例的,Servlet中的非static的成员变量只有一份,多个客户端好比是多个线程,都访问的是同一个空间.

解决方案:	
		
		1:让当前的Servlet实现javax.servlet.SingleThreadMode接口.
		
		  包装只有一个线程放Servelt,如果有多个线程就排队,如此的话,性能超低(已过时).

		2:在Servlet中不要使用成员变量,使用局部变量.

		  每一个用户,每一个请求都会调用service方法.而局部变量在service方法中,每一次都是新的空间.

Struts1,Spring MVC都是线程不安全的,都是单例的和Servelt类似.

Struts2是线程安全的,每一个线程(请求),都是一个新的Action对象.

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

05.HTTP协议的无状态连接

一次会话:可以简单的理解:打开浏览器,访问某一个站点,在该网址内部查看信息,点击超链接等相关的操作,最后关闭浏览器的整个过程,称为一次会话.

HTTP协议:

		有一个特点:无状态连接,服务端不知道上一次是哪一个客户端请求了自己.

无状态连接带来的问题:

			再一次会话中,我们可以查看多个资源,每一个资源都会先发送请求,再响应,每次的请求都是客户端

			发出的,但是,HTTP是无状态的,它不知道上次是谁请求了自己

			也就是说,再一次会话中,多个请求之间无共享数据.

邮箱的会话跟踪图示
邮箱的会话跟踪图示

06.使用参数传递机制解决用户会话跟踪

解决方案:

		1)使用参数传递机制,在每一个请求之间使用参数来传递需要共享的数据.
	
		  http://localhost/param/list?username=lucy

		  可以解决问题,但是请求需要共享的数据全部都暴露在浏览器的地址栏中,不安全.
	
		  如何解决共享数据不暴露在浏览器的地址栏:为什么会在浏览器的地址栏显示.

		  因为:请求的请求行数据:GET/param/list?username=lucy Http/1.1

		如何解决:共享的数据不会在请求头中出现.

		  把共享数据存放到请求头中,此时就不会在浏览器地址栏出现了.--->(Cookie)

		2):Cookie
		
			Cookie是客户端技术,程序把每个用户的数据以cookie的形式写给用户各自的浏览器,当用户使用

			浏览器再去访问服务器中的web资源时,就会带着各自的资源去,这样,web资源处理的就是用户各自

			的数据了.

		3):Session

三:Cookie

07.Cookie的简单运用

Cookie的操作:

	1:创建Cookie对象.
	
			Cookie cookie = new Cookie(String name,String value);

		参数:
		
			name: 该当前Cookie取一个唯一的名字.

			value:存储在Cookie的共享数据,只能是String类型.

			Cookie cookie = new Cookie("currentName","will");

	2:把Cookie放入响应中,响应给浏览器,把共享的数据存储到浏览器中.

			resp.addCookie(cookie);

	3:获取Cookie以及获取Cookie中的数据.因为Cookie存在请求头中,所以应该通过request去获取.

			Cookie[] cs = req.getCookies();

	4:Cookie的中文问题.

			在Cookie中属性名和属性值都不能使用中文.

			//编码
			String name = URLEncoder.encode(msg,"UTF-8");
			System.out.println(name);
			
			//解码
			String str = URLDecoder.decode(name,"UTF-8");
			System.err.println(str);

	5:修改Cookie中指定属性名的属性值.
		
			需求:修改Cookie cookie = new Cookie("currentName","will");			

			方式1:创建一个同名的新的Cookie.
		
			Cookie c = new Cookie("currentName","lucy");

			方式2:获取该Cookie对象,通过setValue方法,重新设置新的value值.
			
			Cookie对象.setValue("新的值");

			注意:别忘了,重新把该Cookie放入响应中:resp.addCookie(c);

	6:Cookie的分类(会话Cookie和持久化Cookie):
		
			会 话Cookie:关闭浏览器之后,Cookie就销毁了.  缺省情况.

			持久化Cookie:Cookie可以保存指定的时间段(3,一周,一个月).
	
			设置Cookie的最大存活时间:cookie对象.setMaxAge(int seconds);
		
			seconds == 0;   删除Cookie.

			seconds <  0;   会话Cookie.

			seconds >  0;   存储指定的秒数

	7:删除Cookie:  cookie对象.setMaxAge(0);

8.Cookie的路径和Cookie的缺陷

	Cookie的domain:
		
			1):设置Cookie的path为"/". 列如:cookie.setPath("/");
	
			2):设置Cookie的domain. 列如:cookie.setDomain(".baidu.com").其中domain中没有指定域名前缀!


	Cookie的缺陷:
			
			1):多个人使用同一台电脑的时候,可以查看浏览器的Cookie,不安全.

			2):Cookie存储中文比较麻烦(得编码再解码).

			3):Cookie的value是String类型,一个Cookie就只能存储一个数据,如果需要存储多个数据,就得使用N个Cookie

			4):一个站点对Cookie有限制:
			
					Cookie大小限制在4KB之内:

					一台服务器在一个客户端最多保存20个Cookie;

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

			5):在设计上就有问题,考虑生活中问题.

					Cookie是浏览器和服务器之间数据交互的凭证.
			
					在生活中,我们是把识别数据存储到服务端.

四:Session

9.Session的原理

	Session其本质就是一个会话Cookie(浏览器关闭之后,Session就失效了).

Session的原理图
Session的原理图

10.Session的简单运用

1:创建和获取Session对象.
	
	HttpSession session = req.getSession(true);

			如果当前请求中存在一个Session对象,就直接返回,如果不存在Session对象,就先创建一个再返回.

	HttpSession session = req.getSession(false);

			如果当前请求中存在一个Session对象,就直接返回,如果不存在Session对象,就返回null.

	HttpSession session = req.getSession();  等价于:  HttpSession session = req.getSession(true);

2:往Session中存储数据

	Session对象.setAttribute(String name,Object value);

3:从Session中取出数据.

	Object value = session对象.getAttribute(String key);

4:删除Session.(用户注销登录)

	1):删除Session中指定属性名的值.
	
			session对象.removeAttrbute("currentName");
	
	2):销毁Session对象(Session中所有的属性都不存在).
			
			session对象.invalidate();

5:Session的超时管理

	在超时时间之内,如果客户端和服务端没有交互(用户的两次操作不能超过该时间),则自动销毁Session.
	
	session对象.setMaxInactiveInterval(60*10);//超过10分钟,则销毁Session

	Tomcat服务器的默认时间为:30分钟  可以修web.xml文件中的代码
	
	<service-config>
			<session-timeout>15</session-timeout>
	</session-config>

6:URL重写.

	Session是一种特殊的Cookie,而浏览器可以禁用Cookie.

	此时,需要在每一个资源之后,手动的携带session的ID.
	
	/session/list;jsessionid=3FB3D48B84806A040F03B070F7DAE56A
	
	String url = response.encodeURL("/session/list");自动在资源之后拼接;jsessionid=3FB3D48B84806A040F03B070F7DAE56A

	注意:开发中都不会取消接受Cookie的.

11.Session的规范和细节

Session的细节:

		1:一般的,我们存储到Session中的属性名称,要唯一,我们习惯XXX_IN_SESSION;
	
		  session对象.setAttribute("user_in_session","will");

		2:若需要把多个数据存放到Session中,就得调用setAttribute方法N,可以的.
		
		  一般的我们把需要存储的数据,封装成一个对象,然后存储到Session中.
	
		3:如果多台服务器之间需要共享Session,此时Session中的对象必须实现java.io.Serializable(才能在网络上传输).
	
		  序 列 化: 把对象信息存储为二进制.

		  反序列化:把二进制信息恢复成对象.
			
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值