`
paddy.w
  • 浏览: 497980 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Servlet介绍(3)——cookie和session

阅读更多
一、cookie
        cookie的作用:cookie是小段文本信息,Web服务器将它发送给浏览器,然后在访问同一网站或域时,浏览器再将它返回给服务器。这样可以在浏览器端(客户端)保留一些适合保存在客户端的信息(比如用户的用户名、密码,用户访问站点时所使用的模板)。

        cookie的好坏?

        cookie可以很方便的将一些信息存放于客户端,但是存放于客户端有时候会出现一些安全和隐私方面的问题。简单的说,别人使用了你的电脑去访问一个网站,而由于上次你登录网站时选择了保存我的用户名和密码,这个时候访问的网站就会将一段cookie发送给你的机器。这样当其他人使用你的电脑的时候,网站并会不去关系现在是谁在使用你的电脑(网站的实现只关心它找到的你上次登录的cookie),这样别人登录的时候使用的你的帐号,所以可能会引发一些安全上的问题(尤其是公共场合的计算机)。      
        cookie虽然可以保存很多东西,但是由于cookie是存放于客户端的,而浏览器一般不会在客户端存放很多的cookie(磁盘也是要钱的!)一般浏览器都会限制每个cookie的大小(一般是4k),同一个站点的cookie的数量(一般是20),以及浏览器保存的所有cookie的数量(一般是300)。所以我们的应用最好不要使用太多的cookie。   
        cookie的使用很方便。服务器端需要向客户端发送cookies时只需要调用几个简单的函数即可以完成:      
        Cookie cookie = new Cookie(String name, String value)
        构造一个cookie对象,cookie的名字为name,cookie的值为value
        cookie.setMaxAge(int expiry) //void setMaxAge(int expiry)
        设定一个cookie存在的时间(毕竟不会让它一直存在的),存在于客户端的参数为expiry秒。特殊的是当expiry值为-1的时候,代表关闭当前浏览器即失效。
        httpServletResponse.addCookie(cookie)  //HttpServletResponse  void addCookie(Cookie cookie)
        调用这个方法才会将cookie发送至客户端。这样即可以将以name为名字,value为值的cookie保存至客户端。当服务器端需要判断请求的客户是否有以前的cookie时只需要调用 httpServletRequest.getCookies() // HttpServletRequest Cookie[] getCookies()
该方法返回一个request中包含的cookie的数组,当没有cookie存在时,返回值为null。所以对cookies数组做迭代时,还是要先判断一下是否为null;       

        下面以一个例子(两只Servlet程序)来结束cookie本部的介绍,关于cookie的其他方法可以查看api:

LoginServlet:
public class LoginServlet extends HttpServlet { 

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 

		Cookie[] cookies = request.getCookies(); 
		Cookie cookie = null; 
		String userName = null; 
		String password = null; 
		boolean check = false; 

		if(cookies != null) 
			for(int i = 0; i < cookies.length; ++i) { 
				cookie = cookies[i]; 

				if(cookie.getName().equals("UserName")) 
					userName = cookie.getValue(); 
				if(cookie.getName().equals("Password")) 
					password = cookie.getValue(); 
				if(cookie.getName().equals("Check")) 
					check = cookie.getValue().equals("Yes") ? true:false; 
			}

		response.setContentType("text/html"); 
		PrintWriter out = response.getWriter(); 
		String docType ="<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">";
		String title = "Login";
		out.println(docType + "<HTML> " + "<HEAD><TITLE>" + title 
				+ "</TITLE></HEAD> " + "<BODY BGCOLOR=\"#FDF5E6\"> " 
				+ "<CENTER> " + "<H1>" + title + "</H1> " 
				+ "<FORM ACTION=\"LoginControlServlet\" METHOD=\"POST\">" 
				+(userName==null? "UserName:<INPUT TYPE=\"TEXT\" NAME=\"UserName\"><BR>" : "UserName:<INPUT TYPE=\"TEXT\" NAME=\"UserName\" VALUE=\"\"+ userName + \"\"><BR>") 
				+(password==null? "Password:<INPUT TYPE=\"PASSWORD\" NAME=\"Password\"><BR>" : "Password:<INPUT TYPE=\"PASSWORD\" NAME=\"Password\" VALUE=\"\"+ password + \"\"><BR>") 
				+(check ? "<INPUT TYPE=\"CHECKBOX\" NAME=\"Check\" CHECKED=\"true\">": "<INPUT TYPE=\"CHECKBOX\" NAME=\"Check\">") 
				+ "Don''t Ask Me Again" 
				+ "<CENTER><INPUT TYPE=\"SUBMIT\" VALUE=\"Login\"></CENTER>" 
				+ "</FORM>" 
				+"</CENTER></BODY></HTML>"); 
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
		this.doGet(request, response); 
	}
}


LoginControlServlet:
public class LoginControlServlet extends HttpServlet { 

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 

		if(request.getParameter("Check")!= null && request.getParameter("Check").equals("on")) { 
			Cookie cookie1 = new Cookie("Check","Yes"); 
			cookie1.setMaxAge(3600 * 24 *30); 
			response.addCookie(cookie1); 
			Cookie cookie2 = new Cookie("UserName",request.getParameter("UserName")); 
			cookie2.setMaxAge(3600 * 24 *30); 
			response.addCookie(cookie2); 
			Cookie cookie3 = new Cookie("Password",request.getParameter("Password")); 
			cookie3.setMaxAge(3600 * 24 *30); 
			response.addCookie(cookie3); 
		}

		response.setContentType("text/html"); 
		PrintWriter out = response.getWriter(); 
		String docType = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"> "; 
		String title = "Login"; 

		out.println(docType + "<HTML> " + "<HEAD><TITLE>" + title 

				+ "</TITLE></HEAD> " + "<BODY BGCOLOR=\"#FDF5E6\"> " 

				+ "<CENTER> " + "<H1>" + title + "</H1> " 

				+"UserName:" + request.getParameter("UserName") + "<BR>" 

				+"Password:" + request.getParameter("Password") + "<BR>" 

				+"</CENTER></BODY></HTML>"); 
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
		this.doGet(request, response); 
	}
}


        LoginServlet和LoginControlServlet 分别 mapping至 /LoginServlet和/ LoginControlServlet。然后第一次访问http://127.0.0.1:8080/train/LoginServlet登录时不选择don’t ask me again,然后关掉窗口。第二次重新打开上面的url选择don’t ask me again 登录后关掉窗口。第三次访问时则不会再述要输入用户名和密码。PS:用户名、密码随便输入即可


二、session

        由于http协议是一种无状态的协议,所以不通过其他手段的话,很难记录用户之前做过哪些事情。记录用户的状态,固然用cookie可以实现,但是cookie的大小和数量是存在限制的,并且还是存放于客户端的(客户端的cookie可以被人为的删除,而且在安全性上也是存在问题)。
session则和cookie的实现不一样,session是存放于服务器端的(基本可以理解成我们想放什么就可以放什么,我们想放多少就放多少)。session的实现机制,session既然是存在于server端的。那么我们当我们访问一个server的时候,server是如何找到我们对应的session的呢?一般情况下,当server端为一个用户创建一个session之后会将一个cookie,cookie的name为JSESSIONID,对应的值为一个字符串传递给client端,client端再次访问server端的时候,server会根据cookie中的JSESSIONID的值,来找到存放于server端的session。(浏览器禁用cookie的时候,我们可以将jseesionid和其对应的值显示在用户访问的每一个url上,当然用户禁用cookie的情况还是很少的,现在绝大多数浏览器默认页是支持cookie的。故这里不多讨论其实现的方式)
在我们使用session的时候,当然不需要自己用cookie这些东西去实现,我们只需要几个简单的调用即可以完成了。
        首先我们需要获取一个session,获取一个session可以调用HttpServletRequest对象的HttpSession getSession()和HttpSession getSession(boolean create)来获取。HttpSession getSession()调用该方法返回一个session。当已经存在client端在server端已经存在session时,即返回已经存在的session。当session不存在时及创建一个新的session。所以这个调用不会给我们返回nullHttpSession getSession(boolean create)当参数create的值为true时,该调用等价于HttpSession getSession()。当参数create的值为false时,则client端在server端已经存在session时,返回已经存在的session,但是如果client端在server端还没有session时,则返回null。(通过这种参数为false的调用,我们可以实现当用户直接访问我们的网站的时候,我们让他直接去登陆页面。。。登录以后才能查看里面的内容)取得session之后使用起来也很简单,基本使用以下几个方法即可  
        void setAttribute(String name, Object value)

        Object getAttribute(String name)

        void removeAttribute(String name)

        void setAttribute(String name, Object value)
        向session中添加一个名字为name,值为value的键值对(注意了哦,这里的value的类型是Object而不再是String)。当name已经在session中存在时,则替换name对应的值为value。

        Object getAttribute(String name)
        这个好像没有什么好说的,返回name对应的value。当然name不存在时候会返回null

        void removeAttribute(String name)
        删除name对应的键值对。

        Session其他常用的几个方法:

        void setMaxInactiveInterval(int interval)
        设置一个session当用户在interval秒内没有活动时即失效 (利用这个我们可以很方便的实现,当用户多长时间没有和我们的网站有任何交互时候让其需要重新登录才能继续浏览),如果不调用这个方法的话会根据容器的默认设置(一般为30分钟)

        void invalidate()
        将此session对象立即失效(会释放session占用的一些资源)(利用这个方法可以解决我们访问一个网站时,突然需要离开但不想关闭浏览器窗口。如果我离开后不希望别人能继续使用我已经登录的帐号做其他操作则可以提供一个注销的功能给用户,当用户点击注销的时候即调用此方法)。


        下面还是一个例子,此例子包含的.java文件可能比较多:

        先看下我们用于存放于session中的对象:User类
public class User implements Serializable {

	public User() { }

	public User(String name, String password) {
		this.name = name;
		this.password = password;
	}

	private String name = "";
	private String password = "";

	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
}


SessionLogin:
public class SessionLogin extends HttpServlet { 
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
		Cookie[] cookies = request.getCookies(); 
		Cookie cookie = null; 
		String userName = null; 
		String password = null; 
		boolean check = false; 
		if(cookies != null) 
			for(int i = 0; i < cookies.length; ++i) { 
				cookie = cookies[i]; 
				if(cookie.getName().equals("UserName")) 
					userName = cookie.getValue(); 
				if(cookie.getName().equals("Password")) 
					password = cookie.getValue(); 
				if(cookie.getName().equals("Check")) 
					check = cookie.getValue().equals("Yes") ? true:false; 
			} 
		response.setContentType("text/html"); 
		PrintWriter out = response.getWriter(); 
		String docType = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"> "; 
		String title = "Login"; 
		out.println(docType + "<HTML> " + "<HEAD><TITLE>" + title 
				+ "</TITLE></HEAD> " + "<BODY BGCOLOR=\"#FDF5E6\"> " 
				+ "<CENTER> " + "<H1>" + title + "</H1> " 
				+ "<FORM ACTION=\"SessionLoginControl\" METHOD=\"POST\">" 
				+(userName==null? "UserName:<INPUT TYPE=\"TEXT\" NAME=\"UserName\"><BR>" : "UserName:<INPUT TYPE=\"TEXT\" NAME=\"UserName\" VALUE=\"\"+ userName + \"\"><BR>") 
				+(password==null? "Password:<INPUT TYPE=\"PASSWORD\" NAME=\"Password\"><BR>" : "Password:<INPUT TYPE=\"PASSWORD\" NAME=\"Password\" VALUE=\"\"+ password + \"\"><BR>") 
				+(check ? "<INPUT TYPE=\"CHECKBOX\" NAME=\"Check\" CHECKED=\"true\">": "<INPUT TYPE=\"CHECKBOX\" NAME=\"Check\">") 
				+ "Don''t Ask Me Again" 
				+ "<CENTER><INPUT TYPE=\"SUBMIT\" VALUE=\"Login\"></CENTER>" 
				+ "</FORM>" 
				+"</CENTER></BODY></HTML>"); 
	} 

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
		this.doGet(request, response); 
	} 
}


SessionLoginControl:
public class SessionLoginControl extends HttpServlet { 
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
		if(request.getParameter("Check")!= null && request.getParameter("Check").equals("on")) {
			Cookie cookie1 = new Cookie("Check","Yes");
			cookie1.setMaxAge(3600 * 24 *30);
			response.addCookie(cookie1);
			Cookie cookie2 = new Cookie("UserName",request.getParameter("UserName"));
			cookie2.setMaxAge(3600 * 24 *30);
			response.addCookie(cookie2);
			Cookie cookie3 = new Cookie("Password",request.getParameter("Password"));
			cookie3.setMaxAge(3600 * 24 *30);
			response.addCookie(cookie3);
		}

		HttpSession session = request.getSession();
		session.setAttribute("user", new User(request.getParameter("UserName"),request.getParameter("Password")));
		response.sendRedirect("SessionAttributeShow");
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		this.doGet(request, response);
	}
}


SessionAttributeShow:
public class SessionAttributeShow extends HttpServlet {
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
		HttpSession session = request.getSession(false);
		if(session == null) {
			response.sendRedirect("SessionLogin");
			return;
		}
		User user = (User)session.getAttribute("user");
		if(user == null) {
			response.sendRedirect("SessionLogin");
			return;
		}
		response.setContentType("text/html");
		PrintWriter out = response.getWriter();
		String docType = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"> ";
		String title = "Login";
		out.println(docType + "<HTML> " + "<HEAD><TITLE>" + title
				+ "</TITLE></HEAD> " + "<BODY BGCOLOR=\"#FDF5E6\"> "
				+ "<CENTER> " + "<H1>" + title + "</H1> "
				+"UserName:" + user.getName()+ "<BR>"
				+"Password:" + user.getPassword() + "<BR>"
				+"</CENTER></BODY></HTML>");
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		this.doGet(request, response);
	}
}


        将SessionLogin,SessionLoginControl,SessionAttributeShow分别mapping至/SessionLogin,/SessionLoginControl,/SessionAttributeShow

        访问http://127.0.0.1:8080/train/SessionLogin进行测试,输入用户名密码可以在http://127.0.0.1:8080/train/SessionAttributeShow中看到输入内容,但是假如直接访问http://127.0.0.1:8080/train/SessionAttributeShow则会退到http://127.0.0.1:8080/train/SessionLogin要求你进行登录。

        session的其他注意点,session中的对象是一直存在的,除非你手动的remove或者session失效,所以我们做应用的时候需要考虑什么东西是我们真的需要存放于session中的,session也需要占用内存和磁盘上的空间,session中存放大量对象将对系统性能产生很大的影响,对内存和资源的消耗也会增加。

        由于容器一般会在内存不足时将不常用的session由内存转移(个人习惯叫钝化,反之为锐化)到磁盘。所以存放于session中的对象请实现java.io.Serializable接口,要不可能在特定的情况下因session中对象无法序列化而产生java.io.NotSerializableException
分享到:
评论
3 楼 烏魯奇奧拉 2012-11-05  
共进步
2 楼 paddy.w 2012-10-31  
烏魯奇奧拉 写道
  Cookie cookie = Cookie(String name, String value)
错了吧

失误 感谢指出
1 楼 烏魯奇奧拉 2012-10-15  
  Cookie cookie = Cookie(String name, String value)
错了吧

相关推荐

    Cookie与Session的介绍即使用————Cookie

    1.认识Cookie 1.简要介绍: 作用: Cookie是一种会话技术,用来将会话过程中的数据保存到用户的浏览器中,从而使浏览器和服务器更好的实现数据...3.Cookie使用案例 ↓ 类名为Cookiedome的servlet中,代码如下,负责生成

    基于jsp做的期末作品——蛋糕商城

    主要是利用jsp 中的servlet、cookie、session技术做的简单版的jsp期末作品,其中包含了数据库等一切资源。

    JavaWeb12-文件上传.rar

    JavaWeb03-会话跟踪cookie与session.rar JavaWeb04-内置对象与include指令.rar JavaWeb05-购物车.rar JavaWeb06-Servlet.rar JavaWeb07-javaWeb模式.rar JavaWeb08-DBUtil.rar JavaWeb09-EL与JSTL.rar JavaWeb10-...

    javaweb开发购物街系统

    使用servlet开发大型电商系统——购物街。该系统实现了用户的注册登录、商品信息的模糊查询、查看商品详情、加入购物车、确认购物车的订单、提交订单以及用户的后台数据管理等功能。在系统的开发中使用EL表达式JSTL...

    JAVA WEB典型模块与项目实战大全

    7.3 指点迷津——cookie知识  7.4 统计访问量功能  7.5 指点迷津——session知识  7.6 统计在线人数功能  7.7 小结  第8章 网络购物车(jsp+servlet+javabean)  8.1 网络购物车原理  8.2 实现网络...

    JavaWeb每日总结思维导图

    内容包括:MySQL、MySQL约束&多表、MySQL多表&事务、JDBC、数据库连接池、HTML、CSS、JS基础&高级、BootStrap、XML、Tomcat、Servlet&HTTP&Request、Response、Cookie&Session、JSP&EL&JSTL、Filter&Listener、...

    深入体验Java Web开发内幕

    6.8 利用请求域属性传递信息  6.9 请求参数的中文读取问题  6.10 思考与实践 第7章 会话与状态管理  7.1 Web应用中的会话与会话状态  7.2 Cookie  7.3 在Servlet程序中使用Cookie  ...

    Java架构直通车——用Redis实现分布式会话

    曾经的Servlet时代(jsp),一旦用户与服务端交互,服务器tomcat就会为用户创建一个session,同时前端会有一个jsessionid,每次交互都会携带。如此一来,服务器只要在接到用户请求时候,就可以拿到jsessionid,并...

    最新Java面试题视频网盘,Java面试题84集、java面试专属及面试必问课程

    │ Java面试题22.Session和Cookie的区别.mp4 │ Java面试题23.mvc模式和mvc各部分的实现.mp4 │ Java面试题24.数据库分类和常用数据库.mp4 │ Java面试题25.关系型数据库的三范式.mp4 │ Java面试题26.事务的四大...

    MLDN+李兴华+Java+Web开发实战经典.part3.rar )

    6.4.3、操作Cookie 6.5、session对象 6.5.1、取得Session Id 6.5.2、登陆及注销 6.5.3、判断新用户 6.5.4、取得用户的操作时间 6.6、application对象 6.6.1、取得虚拟目录对应的绝对路径 6.6.2、范例...

    李兴华 Java Web 开发实战经典 高清扫描版Part3

    6.4.3、操作Cookie 6.5、session对象 6.5.1、取得Session Id 6.5.2、登陆及注销 6.5.3、判断新用户 6.5.4、取得用户的操作时间 6.6、application对象 6.6.1、取得虚拟目录对应的绝对路径 6.6.2、范例讲解:...

    Google Android SDK开发范例大全(第3版) 3/5

    8.25 WebView网站Session Cookie判断与访问 8.26 文件下载管理器 8.27 手机Socket联机拨号服务器 第9章 Google服务与Android完美整合 9.1 Google账号验证Token 9.2 Google搜索 9.3 前端产生QR Code二维条形码 9.4 以...

    Google Android SDK开发范例大全(第3版) 1/5

    8.25 WebView网站Session Cookie判断与访问 8.26 文件下载管理器 8.27 手机Socket联机拨号服务器 第9章 Google服务与Android完美整合 9.1 Google账号验证Token 9.2 Google搜索 9.3 前端产生QR Code二维条形码 9.4 以...

    Google Android SDK开发范例大全(第3版) 4/5

    8.25 WebView网站Session Cookie判断与访问 8.26 文件下载管理器 8.27 手机Socket联机拨号服务器 第9章 Google服务与Android完美整合 9.1 Google账号验证Token 9.2 Google搜索 9.3 前端产生QR Code二维条形码 9.4 以...

    Google Android SDK开发范例大全(第3版) 5/5

    8.25 WebView网站Session Cookie判断与访问 8.26 文件下载管理器 8.27 手机Socket联机拨号服务器 第9章 Google服务与Android完美整合 9.1 Google账号验证Token 9.2 Google搜索 9.3 前端产生QR Code二维条形码 9.4 以...

    李兴华 Java Web 开发实战经典_带源码_高清pdf 带书签 上

    6.4.3、操作Cookie 6.5、session对象 6.5.1、取得Session Id 6.5.2、登陆及注销 6.5.3、判断新用户 6.5.4、取得用户的操作时间 6.6、application对象 6.6.1、取得虚拟目录对应的绝对路径 6.6.2、范例讲解:...

    李兴华 java_web开发实战经典 源码 完整版收集共享

    6.4.3、操作Cookie 6.5、session对象 6.5.1、取得Session Id 6.5.2、登陆及注销 6.5.3、判断新用户 6.5.4、取得用户的操作时间 6.6、application对象 6.6.1、取得虚拟目录对应的绝对路径 6.6.2、范例讲解:...

    李兴华 Java Web 开发实战经典_带源码_高清pdf 带书签 下

    6.4.3、操作Cookie 6.5、session对象 6.5.1、取得Session Id 6.5.2、登陆及注销 6.5.3、判断新用户 6.5.4、取得用户的操作时间 6.6、application对象 6.6.1、取得虚拟目录对应的绝对路径 6.6.2、范例讲解:...

    李兴华Java Web开发实战经典.pdf (高清版) Part1

    6.4.3、操作Cookie 6.5、session对象 6.5.1、取得Session Id 6.5.2、登陆及注销 6.5.3、判断新用户 6.5.4、取得用户的操作时间 6.6、application对象 6.6.1、取得虚拟目录对应的绝对路径 6.6.2、范例...

Global site tag (gtag.js) - Google Analytics