JSP session与cookie

一、Cookie
   1、Cookie是Web服务器保存在客户端的一系列文本信息。

   2、Cookie的工作原理   

                客户端请求服务器,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个Cookie。客户端浏览器会把Cookie保存起来。当浏览器再请求该网站 时,浏览器把请求的网址连同该Cookie一同提交给服务器。服务器检查该Cookie,以此来辨认用户状态。服务器还可以根据需要修改Cookie的内容。
    

      查看某个网站颁发的Cookie很简单。在浏览器地址栏输入javascript:alert (document. cookie)就可以了(必须有网才能查看)。

   JavaScript脚本会弹出一个对话框显示本网站颁发的所有Cookie的内容,如图1.1所示。

                    

3、Cookie的作用
a) 对特定对象的追踪
b) 统计网页浏览次数
c) 简化登录

4、安全性能
 容易信息泄露


        5、Cookie常用的方法

            

       6、  Cookie的有效期

        Cookie的maxAge决定着Cookie的有效期,单位为秒(Second)。

        Cookie中通过getMaxAge()方法与setMaxAge(int maxAge)方法来读写maxAge属性。

      (1) 如果maxAge为正数,则表示该Cookie会在maxAge秒之后自动失效。浏览器会将maxAge为正数的Cookie持久化,即写到对应的Cookie文件中。无论客户关闭了浏览器还是电脑,只要还在maxAge秒之前,登录网站时该Cookie仍然有效。下面代码中的Cookie信息将永远有效。       

Cookie cookie = new Cookie("username","boy");   // 新建Cookie

cookie.setMaxAge(Integer.MAX_VALUE);           // 设置生命周期为MAX_VALUE

response.addCookie(cookie);                    // 输出到客户端

 

(2)如果maxAge为负数,则表示该Cookie仅在本浏览器窗口以及本窗口打开的子窗口内有效,关闭窗口后该Cookie即失效。maxAge为负数的Cookie,为临时性Cookie,不会被持久化,不会被写到Cookie文件中。Cookie信息保存在浏览器内存中,因此关闭浏览器该Cookie就消失了。Cookie默认的maxAge值为–1。

Cookie cookie = new Cookie("username","boy");   // 新建Cookie

response.addCookie(cookie);                    // 输出到客户端


(3)如果maxAge为0,则表示删除该Cookie。Cookie机制没有提供删除Cookie的方法,因此通过设置该Cookie即时失效实现删除Cookie的效果。失效的Cookie会被浏览器从Cookie文件或者内存中删除,

Cookie cookie = new Cookie("username","boy");   // 新建Cookie

cookie.setMaxAge(0);                          // 设置生命周期为0,不能为负数

response.addCookie(cookie);             // 必须执行这一句


     注意:从客户端读取Cookie时,包括maxAge在内的其他属性都是不可读的,也不会被提交。浏览器提交Cookie时只会提交name与value属性。maxAge属性只被浏览器用来判断Cookie是否过期。

     7、Cookie的修改、删除

 Cookie并不提供修改、删除操作。

         修改某个Cookie,只需要新建一个同名的Cookie,添加到response中覆盖原来的Cookie。

 删除某个Cookie,只需要新建一个同名的Cookie,并将maxAge设置为0,并添加到response中覆盖原来的Cookie。


   8、永久性的登录

          最直接的是把用户名与密码都保持到Cookie中,下次访问时检查Cookie中的用户名与密码,与数据库比较。这是一种比较危险的选择,一般不把密码等重要信息保存到Cookie中

         在登录时查询一次数据库,以后访问验证登录信息时不再查询数据库。实现方式是把账号按照一定的规则加密后,连同账号一块保存到Cookie中。下次访问时只需要判断账号的加密规则是否正确即可!

         账号保存到名为account的Cookie中,把账号连同密钥用MD5算法加密后保存到名为ssid的Cookie中。 验证时验证Cookie中的账号与密钥加密后是否与Cookie中的ssid相等      

<%@page import="java.security.MessageDigest"%>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" isErrorPage="false" %>
<%
	String path = request.getContextPath();
	String basePath = request.getScheme() + "://"
			+ request.getServerName() + ":" + request.getServerPort()
			+ path + "/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">

<title>My JSP 'login.jsp' starting page</title>

<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->

</head>

<%!//常量
	private static final String KEY = ":cookie@myback.com";

	// 密钥 
	public final static String calcMD5(String ss) { // MD5 加密算法
		String s = ss == null ? "" : ss; // 若为null返回空
		char hexDigits[] = { '0', '1', '2', '3', '4', '1', '6', '7', '8', '9',
				'a', 'b', 'c', 'd', 'e', 'f' }; // 字典
		try {
			byte[] strTemp = s.getBytes(); // 获取字节
			MessageDigest mdTemp = MessageDigest.getInstance("MD5"); // 获取MD1
			mdTemp.update(strTemp); // 更新数据
			byte[] md = mdTemp.digest(); // 加密
			int j = md.length; // 加密后的长度
			char str[] = new char[j * 2]; // 新字符串数组
			int k = 0; // 计数器k
			for (int i = 0; i < j; i++) { // 循环输出
				byte byte0 = md[i];
				str[k++] = hexDigits[byte0 >>> 4 & 0xf];
				str[k++] = hexDigits[byte0 & 0xf];
			}
			
			return new String(str); // 加密后字符串
		} catch (Exception e) {
			return null;
		}
	}
%>


<%
	//处理中文乱码
	request.setCharacterEncoding("UTF-8");

	String action = request.getParameter("action"); // 获取action参数

	//判断登录
	if ("login".equals(action)) { //login
	
		//获得账号
		String account = request.getParameter("account");

		//获得密码
		String pwd = request.getParameter("pwd");

		//获得时间
		int timeout = Integer.parseInt(request.getParameter("timeout"));
		
			//out.println("timeout="+timeout);

		if ("sa".equals(account.trim()) && "123".equals(pwd.trim())) {
			//把账号、密钥使用MD1加密后保存
			String ssid = calcMD5(account + KEY);
			
			out.println("ssid="+ssid);

			// 1)新建Cookie account
			Cookie accountCookie = new Cookie("account", account);
			// 设置有效期
			accountCookie.setMaxAge(timeout);

			// 2)新建Cookie ssid
			Cookie ssidCookie = new Cookie("ssid", ssid);
			// 设置有效期  
			ssidCookie.setMaxAge(timeout);

			// 输出到客户端  
			response.addCookie(accountCookie);
			response.addCookie(ssidCookie);

			//重新请求本页面,参数中带有时间戳,禁止浏览器缓存页面内容
			response.sendRedirect(request.getRequestURI() + "?"
					+ System.currentTimeMillis());
	
		}
	} else if ("logout".equals(action)) { //logout
		// 新建Cookie,内容为空
		Cookie accountCookie = new Cookie("account", "");
		// 设置有效期为0,删除
		accountCookie.setMaxAge(0);
		// 新建Cookie,内容为空
		Cookie ssidCookie = new Cookie("ssid", "");
		ssidCookie.setMaxAge(0); // 设置有效期为0,删除
		// 输出到客户端
		response.addCookie(accountCookie);
		response.addCookie(ssidCookie);

		//重新请求本页面,参数中带有时间戳,禁止浏览器缓存页面内容
		response.sendRedirect(request.getRequestURI() + "?"
				+ System.currentTimeMillis());
	
	}
%>
<%
	boolean login = false; // 是否登录
	String account = null; // 账号
	String ssid = null; // SSID标识

	if (request.getCookies() != null) { // 如果Cookie不为空
		for (Cookie cookie : request.getCookies()) { // 遍历Cookie
			if (cookie.getName().equals("account")) // 如果Cookie名为
				account = cookie.getValue(); // 保存account内容
			if (cookie.getName().equals("ssid")) // 如果为SSID
				ssid = cookie.getValue(); // 保存SSID内容
		}
	}
	if (account != null && ssid != null) { // 如果account、SSID都不为空
		login = ssid.equals(calcMD5(account + KEY));
		// 如果加密规则正确, 则视为已经登录
	}
%>


<body>
	<fieldset><legend>当前有效 Cookie</legend>
	
	<%
		if (request.getCookies() != null) { // 如果Cookie不为空
			for (Cookie cookie : request.getCookies()) { // 遍历Cookie
			   out.println("<span style='margin-left:60px; display:block;color:blue;'>"+cookie.getName()+":"+cookie.getValue()+"</span>");
			}
		}
	 %>
 
	</fieldset>
	 <br/>
	<fieldset><legend><%=login ? "欢迎您回来" : "请先登录"%></legend>
	<%
		if (login) {
	%>
	欢迎您, <span style="color:green;font-size:28px;">${ cookie.account.value }</span>   
	<a href="${ pageContext.request.requestURI }?action=logout"> 注销</a>
	<%
		} else {
	%>
	<form action="${pageContext.request.requestURI }?action=login"
		method="post">
		<table border="0">
			<tr>
				<td>账号:</td>
				<td><input type="text" name="account"
					style="width:
                   200px; ">
				</td>
			</tr>
			<tr>
				<td>密码:</td>
				<td><input type="password" name="pwd"></td>
			</tr>
			<tr>
				<td>有效期:</td>
				<td><input type="radio" name="timeout" value="-1" checked>
					关闭浏览器即失效 <br /> <input type="radio" name="timeout"
					value="<%=30 * 24 * 60 * 60%>"> 30天 内有效 <br /> <input
					type="radio" name="timeout" value="<%=Integer.MAX_VALUE%>">
					永久有效 <br /></td>
			</tr>
			<tr>
				<td></td>
				<td><input type="submit" value=" 登  录 " class="button">
				</td>
			</tr>
		</table>
	</form><fieldset>
	<%
		}
	%>
</body>
</html>
如图所示:

       


二、session

1、Session机制

    除了使用Cookie,Web应用程序中还经常使用Session来记录客户端状态。Session是服务器端使用的一种记录客户端状态的机制,使用上比Cookie简单一些,相应的也增加了服务器的存储压力

2、什么是Session

   Session是另一种记录客户状态的机制,不同的是Cookie保存在客户端浏览器中,而Session保存在服务器上。客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上。


3、Session的生命周期

       Session保存在服务器端。为了获得更高的存取速度,服务器一般把Session放在内存里。每个用户都会有一个独立的Session。

如果Session内容过于复杂,当大量客户访问服务器时可能会导致内存溢出。因此,Session里的信息应该尽量精简。

Session在用户第一次访问服务器的时候自动创建。需要注意只有访问JSP、Servlet等程序时才会创建Session,只访问HTML、IMAGE等静态资源并不会创建Session。如果尚未生成Session,也可以使用request.getSession(true)强制生成Session。

Session生成后,只要用户继续访问,服务器就会更新Session的最后访问时间,并维护该Session。用户每访问服务器一次,无论是否读写Session,服务器都认为该用户的Session“活跃(active)”了一次。


4、Session的有效期

       由于会有越来越多的用户访问服务器,因此Session也会越来越多。为防止内存溢出,服务器会把长时间内没有活跃的Session从内存删除。这个时间就是Session的超时时间。如果超过了超时时间没访问过服务器,Session就自动失效了。 Session有效期默认值是1800秒

5、 Session的常用方法

         

6、 Session对浏览器的要求

       HTTP协议是无状态的,Session不能依据HTTP连接来判断是否为同一客户,因此服务器向客户端浏览器发送一个名为JSESSIONID的Cookie,它的值为该Session的id(也就是HttpSession.getId()的返回值)。Session依据该Cookie来识别是否为同一用户。

该Cookie为服务器自动生成的,它的maxAge属性一般为–1,表示仅当前浏览器内有效,并且各浏览器窗口间不共享,关闭浏览器就会失效。

因此同一机器的两个浏览器窗口访问服务器时,会生成两个不同的Session。但是由浏览器窗口内的链接、脚本等打开的新窗口(也就是说不是双击桌面浏览器图标等打开的窗口)除外。这类子窗口会共享父窗口的Cookie,因此会共享一个Session。

    注意:新开的浏览器窗口会生成新的Session,但子窗口除外。子窗口会共用父窗口的Session。例如,在链接上右击,在弹出的快捷菜单中选择“在新窗口中打开”时,子窗口便可以访问父窗口的Session。

7、用户登录
 (1)学生类   
package com.hlx.entity;

import java.util.Date;
/**
 * 学生类
 * @author Administrator
 *
 */
public class Student {
	private String name;  //姓名
	private String pwd;  //密码
	private int age;  //年龄
	private Date birthday; //生日

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getPwd() {
		return pwd;
	}

	public void setPwd(String pwd) {
		this.pwd = pwd;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public Date getBirthday() {
		return birthday;
	}

	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}

	public Student(String name, String pwd, int age, Date birthday) {
		super();
		this.name = name;
		this.pwd = pwd;
		this.age = age;
		this.birthday = birthday;
	}

	public Student() {
		super();
	}

}
 (2)login.jsp页面
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>登录</title>

</head>


<body>
	<fieldset>
		<legend>用户登录</legend>
		<form method="post" action="doLogin.jsp" name="frm">
			<table border="0" width="298" height="133" align="center">
				<tbody>
					<tr>
						<td> 用户名:</td>
						<td> <input type="text" name="uname"></td>
					</tr>
					<tr>
						<td> 密码:</td>
						<td> <input type="password" name="upwd"></td>
					</tr>
					<tr>
						<td> </td>
						<td> <input type="reset" value="重置" name="button4"><input
							type="submit" value="登录" name="button3"></td>
					</tr>
				</tbody>
			</table>
		</form>
	</fieldset>
</body>
</html>

(3)doLogin.jsp处理页面
<%@page import="java.text.SimpleDateFormat"%>
<%@page import="java.text.DateFormat"%>
<%@page import="com.hlx.entity.Student"%>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%!DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); // 日期格式化器%>
<%
	//动态数组对象
	List<Student> students = new ArrayList<Student>();

	//添加学生对象
	students.add(new Student("张三", "123456", 22, dateFormat
			.parse("1993-01-01")));
	students.add(new Student("刘芳", "654321", 18, dateFormat
			.parse("1997-01-01")));
	students.add(new Student("光头强", "098765", 20, dateFormat
			.parse("1995-01-01")));

	//处理中文					
	request.setCharacterEncoding("UTF-8");

	//获得值
	String name = request.getParameter("uname");
	String pwd = request.getParameter("upwd");

   //遍历数据
	for (Student stu : students) {
		//判断 
		if (stu.getName().equals(name.trim()) && stu.getPwd().equals(pwd.trim())) {
			// 登录成功,设置将用户的信息以及登录时间保存到Session
			// 保存登录的Student
			session.setAttribute("stu", stu);
			// 保存登录的时间  
			session.setAttribute("loginTime", new Date());
			
			//跳转
			response.sendRedirect("welcome.jsp");
		} else {	
			out.println("<script>alert('用户名或密码错误!');window.location.href='login.jsp';</script>");
		}

	}
%>

(4)welcome.jsp欢迎页面
<%@page import="com.hlx.entity.Student"%>
<%@page import="com.sun.xml.internal.ws.client.Stub"%>
<%@page import="java.text.SimpleDateFormat"%>
<%@page import="java.text.DateFormat"%>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>

<title>欢迎页面</title>

<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->

</head>

<body>
    <a href="javascript:history.go(-1)">返回</a><p/>
	<%!DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); // 日期格式化器
	   DateFormat dateFormat2 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); // 日期格式化器
	%>
	<%
		Student student = (Student) session.getAttribute("stu"); // 获取登录的student
		Date loginTime = (Date) session.getAttribute("loginTime"); // 获取登录时间
	%>
	<fieldset>
		<legend>用户登录</legend>
	<table style="margin-left: 80px; font-size:14px;line-height: 25px; color: blue">
		<tr>
			<td>您的姓名:</td>
			<td><%=student.getName()%></td>
		</tr>
		<tr>
			<td>登录时间:</td>
			<td><%=dateFormat2.format(loginTime)%></td>
		</tr>
		<tr>
			<td>您的年龄:</td>
			<td><%=student.getAge()%></td>
		</tr>
		<tr>
			<td>您的生日:</td>
			<td><%=dateFormat.format(student.getBirthday())%></td>
		</tr>
	</table></fieldset>
</body>
</html>
 如图所示:
                      
                    
 


    注意程序中Session中直接保存了Student类对象与Date类对象,使用起来要比Cookie方便。

当多个客户端执行程序时,服务器会保存多个客户端的Session。获取Session的时候也不需要声明获取谁的Session。Session机制决定了当前客户只会获取到自己的Session,而不会获取到别人的Session。各客户的Session也彼此独立,互不可见

提示Session的使用比Cookie方便,但是过多的Session存储在服务器内存中,会对服务器造成压力。

三、cookie 和session 的区别:

1、session是在服务器端保存用户信息,Cookie是在客户端保存用户信息
2、session中保存的是对象,Cookie保存的是字符串
3、session随会话结束而关闭,Cookie可以长期保存在客户端
4、Cookie通常用于保存不重要的用户信息,重要的信息使用session保存


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值