Session和Application

Session与Cookie不同的是,它是写在服务器端的。当一个浏览器链接到服务器后,服务器会为这个浏览器分配一块特定的内存来存储session的信息。但是当有很多客户端访问服务器时,服务器会为他们分配很多session的内存用于存储每个客服端访问服务器时产生的信息,比如订单等,那么,这些session怎么和每个客户端一一对应呢?这里的解决办法是给每一个客户端一个独一无二的SessionID,而这个SessionID是与session一一对应的。当一个客户端离开当前页面与服务器另一个页面交互时,服务器会根据这个客户端特有的SessionID,找到与他对于的session,从而拿到他之前与服务器其他页面交互时留下的信息,以便进行下一步操作。

那么,新的问题是,这个SessionID存储在什么地方呢?以浏览器访问服务器为例,只要浏览器没有禁用掉Cookie,那么他是通过Cookie存储在浏览器里面的,生命周期和当前的浏览器窗口一样,当浏览器窗口关闭时,Cookie消失。

如果浏览器禁用掉了Cookie,那么必须要自己编程,重写encodeURL()方法,使得重新发起页面请求时,在请求的URL后面带着上一个页面产生的SessionID。


以登陆邮箱为例综合分析Cookie和Session在其中发挥的作用:

 当输入用户名和密码的时候点击登陆后,服务器会分配给客户端一个SessionID,这个sessionID要么存储在Cookie中,要么跟在下一次请求的URL后面。这样,进入到读取邮件信息页面时,通过客户端的SessionID找到服务器里对应的Session(里面存在说明用户已经登陆的信息),从而得以判断当前请求的用户确实已经登陆过了,这时才会让你有权限读取邮件。

同时,经常在登陆页旁有一个“一个星期内自动登陆”的选项。实际上,勾选了这个选项后,服务器就会通过向客户端写入cookie的方式,将登陆信息写入本地磁盘文件,并且保存一个星期,这样下次登陆时直接读取cookie里面的信息,从而实现自动登陆。

下面的代码为一段关于用session实现记录页面访问次数的功能。


import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class TestSession extends HttpServlet {

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		//整个功能用来记录该页面的访问次数
		PrintWriter pw = resp.getWriter();//向客户端写数据的流
		HttpSession session = req.getSession(true);
		Integer accessCount = (Integer)session.getAttribute("access");//拿到session里的值
		if(accessCount == null){
			accessCount = new Integer(0);
		}else{
			accessCount = new Integer(accessCount.intValue()+1);
		}
		session.setAttribute("access", accessCount);//向session里设置值
		pw.println(accessCount);
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		doGet(req,resp);
	}
	

}

当在浏览器里访问这个sevlet时,因为这个计数器是通过session存储存储的,也就是说是与每一个客户端一一对应的。当关掉当前页面再启一个页面重新访问这个servlet时,会发现计数又重新从零开始。注意,这点与application的区别。

下面这段代码通过application来实现计数功能。


import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class TestApplication extends HttpServlet {

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		ServletContext application = this.getServletContext();//拿到当前webApplication的上下文
		PrintWriter pw = resp.getWriter();
		Integer accessCount = (Integer) application.getAttribute("access");
		if(accessCount == null){
			accessCount = new Integer(0);
		}else{
			accessCount = new Integer(accessCount.intValue()+1);
		}
		application.setAttribute("access", accessCount);
		pw.println(accessCount);
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// TODO Auto-generated method stub
		super.doPost(req, resp);
	}
	
}

当在浏览器中访问这个servlet时,即使关掉当前页面重新再启一个页面,计数也会从上一个页面的数字继续增加。这就是application的特点。

每一个服务器上面可能会有很多个webApplication,而每一个webApplication里面则可能会有很多个servlet对外提供服务。每一个webApplication都有自己的Context,也就是这整个webApplication运行的环境,application的内容就是存储在这个Context里面的,所以所有的客户端都可以访问,而不像session那样每个客户端都有自己特定的一块用来存储session信息,而且只能自己独自访问。






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值