第七章Cookie和Session

本章主干知识点:

1、Cookie:Cookie在Http中的位置;Cookie案例;

2、Session:Session使用;过期问题;Session案例(登录注册);Session原理;

 

第 1 节1-Cookie入门

第 2 节2-Cookie的有效期

第 3 节3-Cookie案例:记住密码

第 4 节4-Cookie注意的问题1

第 5 节5-Cookie注意的问题2

第 6 节6-Session入门

第 7 节7-Session的应用

第 8-13 节8-Session案例:登录注册1 -6

第 14 节14-Session原理简介

第 15 节15-自己开发一个模拟Session

第 16 节16-关于Session的补充

 

    1. Cookie是在浏览器中存储的和具体网站相关的一堆数据,并且每次向服务器请求的时候除了发送表单参数外,还会将和站点相关的所有Cookie都提交给服务器。Cookie是保存在浏览器端的,而且浏览器会在每次请求的时候都会把和这个站点的相关的Cookie提交到服务器,并且将服务端返回的Cookie更新回数据库,因此可以将信息保存在Cookie中,然后在服务器端读取、修改(看报文)。

    2. 在服务器端控制Cookie案例,实现记住用户名的功能

     设置值Cookie cookieUserName = new Cookie("userName",userName); response.addCookie(cookieUserName);

     读取值:遍历req.getCookies(),封装一个Cookie getCookie(HttpServletRequest req, String cookieName)方法;

    3. 如果不设定MaxAge(或者是负值)那么生命周期则是关闭浏览器则终止,否则“最多”到MaxAge(以秒为单位)的时候终止。案例:登录用户名“保存7天”。

     4.Cookie的缺点: Cookie是不可信的;还不能存储过多信息,机密信息不能存(不要把不希望用户看到的或者不能被用户篡改的信息放到Cookie)。Cookie:是可以被清除,不能把不能丢的数据存到Cookie中,也许没到Expires就已经过期了。删除Cookie的方法:设定setMaxAge为0。

 

【总结】

1、Cookie是浏览器负责维护的,和某个网站相关的一块数据存储区域。

2、浏览器向服务器发出请求的时候,就会把这个网站的cookie数据存储区域的数据发给服务器。请求报文头是:Cookie:JSESSIONID=2DA4221DBEDEF330E342E1FD5B5C8D1B; username=admin;age=5

3、Http服务器 可以通过Set-Cookie报文头告诉服务器“再给你一点数据,存起来吧!”,浏览器就会存起来。并且从此之后再向服务器发请求就要把他们都带着。

4、服务器端读取:

                          for(Cookiecookie : req.getCookies())

                          {

                                   resp.getWriter().print("name="+cookie.getName()+"="

                                                     +",value="+cookie.getValue()+"<br/>");

                          }

服务器端写入(生成Set-Cookie报文头)

                          Cookiecookie1 = new Cookie("username","admin");

                          Cookiecookie2 = new Cookie("age","5");

                          resp.addCookie(cookie1);

                          resp.addCookie(cookie2);//把新增的Cookie数据返回给浏览器

 

【Cookies1Servlet.java】

package com.rupeng.test;

import java.io.IOException;

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

public class Cookies1Servlet extends HttpServlet
{
		@Override
		protected void doGet(HttpServletRequest req, HttpServletResponse resp)
				throws ServletException, IOException {
			String action = req.getParameter("action");
			if(action.equals("write"))
			{
				Cookie cookie1 = new Cookie("username","admin");
				Cookie cookie2 = new Cookie("age", "5");
				cookie1.setMaxAge(60);//设定cookie存活时间
				resp.addCookie(cookie1);
				resp.addCookie(cookie2);
				
			}
			else if(action.equals("read"))
			{
				Cookie[] cookies = req.getCookies();
				if(cookies!=null)
				{
					for(Cookie cookie : cookies)
					{
						resp.getWriter().println("name="+cookie.getName()+" "+",value="+cookie.getValue());
					}
				}
			}
			else if(action.equals("del"))
			{
				Cookie cookie = new Cookie("age","");
				cookie.setMaxAge(0); //时间为0  删除
				resp.addCookie(cookie);
			}
		}
		@Override
		protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		this.doGet(req, resp);
		}
}

Cookie的有效期

向服务器申请啥的时候都会带着Cookie。向别的网站请求的时候则不会。Set-Cookie是叠加的。

 

Cookie的setMax以秒为单位,是从Set-Cookie开始maxAge秒之后浏览器就可以这一条Cookie删掉(浏览器删的)了

 

如果不设定setMaxAge,那么Cookie是在浏览器关掉之后清除,否则就是制定的秒钟后删除(无论浏览器是不是还在运行)。如果想让Cookie保存到浏览器下次重启还能看到,那么就要用setMaxAge

 

Cookie容量有限 4k

 

【Cookie深入(*)】

 

1.Cookie无法跨不同的浏览器。ie登一个、Chrome登一个。挂号。

2.Cookie无法跨域名读写。www.rupeng.com无法读写www.qq.com的;  www.rupeng.com无法读写www.rupeng.cn的Cookie。

3.(*)子域名的问题:www.rupeng.com设置的Cookie默认无法被bbs.rupeng.com读写,如果要想能够操作,则需要写入Cookie的时候设置Domain为“.rupeng.com”

 

Session (会话)

 

1.需要一种“服务器端的Cookie”:医生需要一个私人账本,记录病人编号和身份的对应关系。毒品医生,由于身份证无法造假,所以能够保证信息不被假冒。两点:身份证无法造假,这个身份证就可以唯一标识这个用户;核心信息放到服务器上,客户端无法去篡改。

2.Cookie不能存储机密数据。要使用JavaWeb已经内置的Session机制。req.getSession().setAttribute("userName",userName);

 

3.Cookie是存在客户端,Session是存在服务器端,目的是一样的:保存和当前客户端相关的数据(当前网站的任何一个页面都能取到Session)。Session默认放到服务器内存中,所以web服务器重启就消失了

 

4.Session有自动销毁机制,如果一段时间内浏览器没有和服务器发生任何的交互,则Session会定时销毁。这也就是为什么一段时间不操作,系统就会自动退出。

 

5.在web.xml的system.web节点下配置超时时间(单位为分钟)

<session-config>

         <session-timeout>30</session-timeout>

</session-config>

 

Session 案例

1.Session实现登陆。一个登录页面,还有主页面,在主页面中如果用户没登陆,则跳转到登陆页面;登录的话则显示当前登录的用户名。

2.上面的例子用Cookie实现可以吗?为什么?

 

 

【SessionSevlet.java】

package com.rupeng.test;
	
	import java.io.IOException;
	
	import javax.servlet.ServletException;
	import javax.servlet.http.HttpServlet;
	import javax.servlet.http.HttpServletRequest;
	import javax.servlet.http.HttpServletResponse;
	
	public class Session2Servlet extends HttpServlet
	{
			@Override
			protected void doGet(HttpServletRequest req, HttpServletResponse resp)
					throws ServletException, IOException {
				this.doPost(req, resp);
			}
			@Override
			protected void doPost(HttpServletRequest req, HttpServletResponse resp)
				throws ServletException, IOException {
				
				String action = req.getParameter("action");
			if(action.equals("login"))
			{
				req.getRequestDispatcher("Login.jsp").forward(req, resp);
				
			}
			else if(action.equals("loginSubmit"))
			{
				String username = req.getParameter("username");
				String password = req.getParameter("password");
				if(password.equals("123"))
				{
					req.getSession().setAttribute("UserName",username);
					resp.sendRedirect("session2?action=main");
				}	
				else
				{
					resp.getWriter().print("error");
				}
				
			}
			else if(action.equals("main"))
			{
				//从session中读取”登录用户名“
				String username = (String)req.getSession().getAttribute("UserName");
				//如果读不到,则说明用户没有登录,冲定向到登录页面
				if(username==null)
				{
					resp.sendRedirect("session2?action=login");
				}
				else
				{
					//把当前登录的用户名username给到Main.jsp显示
					req.setAttribute("UserName", username);
					req.getRequestDispatcher("Main.jsp").forward(req, resp);
				}
				
				}
			}
	}

【Login.jsp】


<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="session2" method="post">
<input type="hidden"  name="action" value="loginSubmit"/>
		username:<input type="text"  name="username"/>
		password:<input type="text" name="password"/>	
		<input type="submit" value="保存"/>
</form>
</body>
</html>

Session案例2

1.实现正式交付要求的登录注册:带验证码,存到数据库中。 Session的销毁invalidate()(关闭浏览器服务器的Session还会存在一段时间, invalidate()则直接销毁服务器session),退出登录的实现

2.在服务器端的其他Servlet、JSP中都可以访问Session。

 

项目列表:

【Login.jsp】

【CaptchaServlet.java】

【Register.jsp】

【Main.jsp】

【UserDAO.java】

【RuPengUtils.java】

【UserServlet.java】

【MainServlet.java】

【UserInfo.java】

 

 

【Login.jsp】

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>登录</title>
<script type="text/javascript">
	window.οnlοad=function(){
		document.getElementById("login").οnclick=function(){
			var username = document.getElementById("username").value;
			var password = document.getElementById("password").value;
			var yzm = document.getElementById("yzm").value;
			if(username=="")
			{
				alert("用户名必填!");
				return false;
			}
			if(password=="")
			{
				alert("密码必填!");
				return false;
			}
			if(yzm=="")
			{
				alert("验证码必填!");
				return false;
			}
		};		
	};
</script>
</head>
<body>
	<form method="post" action="user">
		<input type="hidden" name="action" value="loginSubmit"/>
	<table>
		<tr><td>用户名:</td><td><input id="username" type="text" name="username"/></td></tr>
		<tr><td>密码:</td><td><input id="password" type="password" name="password"/></td></tr>
		<tr><td>验证码:</td><td><input id="yzm" name="yzm" type="text" /><img src="yzm"/></td></tr>
		<tr><td><input type="submit" id="login" value="登录"/></td><td><a href="user?action=register">注册</a></td></tr>
	</table>
	</form>
</body>
</html>

【CaptchaServlet.java】


package com.rupeng.myweb5;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class CaptchaServlet extends HttpServlet
{
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException
	{
		resp.setContentType("image/jpeg");
		BufferedImage img = new BufferedImage(100, 30,
				BufferedImage.TYPE_3BYTE_BGR);
		Graphics2D g = img.createGraphics();
		g.setColor(Color.red);
		g.setFont(new Font("宋体", Font.BOLD, 30));
		String randNum = createRandNum();
		
		req.getSession().setAttribute("YZM", randNum);//把生成的验证码放到Session中
		//不能放到Cookie等浏览器端可以接触的地方。必须放到服务器中
		
		g.drawString(randNum, 0, 25);
		g.dispose();

		ImageIO.write(img, "JPEG", resp.getOutputStream());

	}

	static String createRandNum()
	{
		char[] nums = { 'a', 'c', 'd', 'e', 'f', 'h', 'k', 'm', 'n', 's', 't',
				'w', 'x', 'y', 'z', '2', '3', '4', '5', '7', '8' };
		String randNum = "";
		Random rand = new Random(System.currentTimeMillis());
		for (int i = 0; i <= 4; i++)
		{
			randNum += nums[rand.nextInt(nums.length)];
		}
		return randNum;
	}

}

【Register.jsp】


<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>注册</title>
<script type="text/javascript">
	window.οnlοad=function(){
		document.getElementById("submit").οnclick=function(){
			var username = document.getElementById("username").value;
			var password = document.getElementById("password").value;
			var password2 = document.getElementById("password2").value;
			var yzm = document.getElementById("yzm").value;
			if(username=="")
			{
				alert("用户名必填!");
				return false;
			}
			if(password=="")
			{
				alert("密码必填!");
				return false;
			}
			if(password!=password2)
			{
				alert("两次输入的密码不一致!");
				return false;
			}
			if(yzm=="")
			{
				alert("验证码必填!");
				return false;
			}
		};	
		document.getElementById("imgYzm").οnclick=function(){
			this.src="yzm?"+Math.random();	
			//alert(this.src);
			//this.src="yzm?t="+new Date();
			//alert(this.src);
		};
	};
</script>
</head>
<body>
	<form method="post" action="user">
		<input type="hidden" name="action" value="registerSubmit"/>
		<table>
			<tr><td>用户名:</td><td><input id="username" type="text" name="username"/></td></tr>
			<tr><td>密码:</td><td><input id="password" type="password" name="password"/></td></tr>
			<tr><td>重复密码:</td><td><input id="password2" type="password" name="password2"/></td></tr>
			<tr><td>验证码:</td><td><input id="yzm" type="text" name="yzm" /><img id="imgYzm" src="yzm"/></td></tr>
			<tr><td><input type="submit" id="submit" value="注册"/></td><td></td></tr>
		</table>
	</form>
</body>
</html>

【Main.jsp】


<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
这是一个登录之后才可以访问的页面<br/>
欢迎您 ${sessionScope.UserName}
</body>
</html>

【RuPengUtils.java】


package com.rupeng.myweb5;

import java.io.IOException;
import java.io.UnsupportedEncodingException;

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

public class RupengUtils
{
	/**
	 * 从请求中获取名字为name的值,解决中文乱码问题
	 * @param req
	 * @param name
	 * @return
	 */
	public static String getParameter(HttpServletRequest request, String name)
	{
		try
		{
			String value = request.getParameter(name);
			byte[] bytes;
			bytes = value.getBytes("ISO-8859-1");
			return new String(bytes, "UTF-8");
		} catch (UnsupportedEncodingException e)
		{
			throw new RuntimeException(e);
		}
	}
	
	/**
	 * 在/Error.jsp中显示错误消息
	 * @param request
	 * @param response
	 * @param msg
	 * @throws ServletException
	 * @throws IOException
	 */
	public static void showError(HttpServletRequest request,HttpServletResponse response,String msg)
	throws ServletException, IOException
	{
		request.setAttribute("errorMsg", msg);
		request.getRequestDispatcher("/Error.jsp").forward(request, response);
	}
	
	/**
	 * 判断一个字符串是否是null或者是否是长度为0的字符串
	 * @param s
	 * @return
	 */
	public static boolean isNullOrEmpty(String s)
	{
		return s==null||s.length()<=0;
	}
}

【UserDAO.java】


package com.rupeng.myweb5;

import java.sql.ResultSet;
import java.sql.SQLException;

public class UserDAO
{
	/**
	 * 根据用户名获得用户对象
	 * @param username
	 * @return
	 */
	public static UserInfo getByUserName(String username)
	{
		ResultSet rs = null;
		try
		{
			rs = JdbcUtils.executeQuery(
					"select * from T_Users where UserName=?", username);
			if (rs.next())
			{
				return toModel(rs);
			} else
			{
				return null;
			}
		} catch (SQLException e)
		{
			throw new RuntimeException(e);
		} finally
		{
			JdbcUtils.closeAll(rs);
		}
	}

	public static UserInfo toModel(ResultSet rs) throws SQLException
	{
		UserInfo user = new UserInfo();
		user.setId(rs.getInt("Id"));
		user.setName(rs.getString("UserName"));
		user.setPassword(rs.getString("Password"));
		return user;
	}

	/**
	 * 新增一个用户
	 * @param userName
	 * @param password
	 */
	public static void addNew(String userName, String password)
	{
		try
		{
			JdbcUtils.executeUpdate(
					"Insert into T_Users(UserName,Password) values(?,?)",
					userName, password);
		} catch (SQLException e)
		{
			throw new RuntimeException(e);
		}
	}

}

【UserServlet.java】


package com.rupeng.myweb5;

import java.io.IOException;
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 UserServlet extends HttpServlet
{
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException
	{
		this.doPost(req, resp);
	}
	
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException
	{
		String action = req.getParameter("action");
		if(action.equals("login"))
		{
			req.getRequestDispatcher("Login.jsp").forward(req, resp);
		}
		else if(action.equals("loginSubmit"))
		{
			String username = RupengUtils.getParameter(req, "username");
			String password = req.getParameter("password");
			String yzm = req.getParameter("yzm");
			if(RupengUtils.isNullOrEmpty(username))	
			{
				RupengUtils.showError(req, resp,"用户名必须填写!");
				return;
			}
			if(RupengUtils.isNullOrEmpty(password))	
			{
				RupengUtils.showError(req, resp,"密码必须填写!");
				return;
			}
			if(RupengUtils.isNullOrEmpty(yzm))	
			{
				RupengUtils.showError(req, resp,"验证码必须填写!");
				return;
			}
			UserInfo user =  UserDAO.getByUserName(username);	
			if(user==null)
			{
				RupengUtils.showError(req, resp, "用户名不存在");
				return;
			}
			if(!user.getPassword().equals(password))
			{
				RupengUtils.showError(req, resp, "密码不正确");
				return;
			}
			
			req.getSession().setAttribute("UserName", username);
			resp.sendRedirect("main");
		}
		else if(action.equals("register"))
		{
			req.getRequestDispatcher("Register.jsp").forward(req, resp);
		}
		else if(action.equals("registerSubmit"))
		{
			String username = RupengUtils.getParameter(req, "username");
			String password = req.getParameter("password");
			String password2 = req.getParameter("password2");
			String yzm = req.getParameter("yzm");
			//因为浏览器有用户禁用js、直接发送Http请求报文等方法跳过检查
			//所以虽然浏览器端做了合法性检查,但是服务器端检查仍然必不可少!
			
			//前端的js检查是“方便用户”,服务器端的检查是“防范坏人”
			if(RupengUtils.isNullOrEmpty(username))	
			{
				RupengUtils.showError(req, resp,"用户名必须填写!");
				return;
			}
			if(RupengUtils.isNullOrEmpty(password))	
			{
				RupengUtils.showError(req, resp,"密码必须填写!");
				return;
			}
			if(!password2.equals(password))	
			{
				RupengUtils.showError(req, resp,"两次输入的密码必须一致!");
				return;
			}
			if(RupengUtils.isNullOrEmpty(yzm))	
			{
				RupengUtils.showError(req, resp,"验证码必须填写!");
				return;
			}
			//比较用户输入的验证码是否和Session中的一致!!
			//验证码放到Session中,只有服务器才能知道“正确的验证码”是什么!
			String yzmInSession = (String)req.getSession().getAttribute("YZM");
			if(!yzmInSession.equals(yzm))
			{
				RupengUtils.showError(req, resp,"验证码填写错误!");
				return;
			}
			
			//todo:检查验证码是否正确
			UserDAO.addNew(username, password);
			resp.sendRedirect("user?action=login");
		}
		else if(action.equals("exit"))//退出登录
		{
			HttpSession session = req.getSession();
			session.invalidate();//销毁Session,把Session数据清除
			resp.sendRedirect("user?action=login");
		}
		else
		{
			req.setAttribute("errorMsg", "action错误");
			req.getRequestDispatcher("Error.jsp").forward(req, resp);
		}
	}
}

【MainServlet.java】


package com.rupeng.myweb5;

import java.io.IOException;

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

public class MainServlet extends HttpServlet
{
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException
	{
		resp.setCharacterEncoding("UTF-8");
		resp.setContentType("text/html;charset=UTF-8");
		String username = (String)req.getSession().getAttribute("UserName");
		if(username==null)
		{
			resp.sendRedirect("user?action=login");//用户没有登录,不能访问,请登录
			return;
		}
		resp.getWriter().println("hello"+username+"<a href='user?action=exit'>退出</a>");
	}
}

【UserInfo.java】


package com.rupeng.myweb5;

public class UserInfo
{
	private int id;
	private String name;
	private String password;

	public int getId()
	{
		return id;
	}

	public void setId(int id)
	{
		this.id = id;
	}

	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;
	}
}

避免恶意写入无效数据到数据库

模拟

 【BaoKu.java】

package com.rupeng.myweb5;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

public class BaoKu
{

	/**
	 * @param args
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException
	{
		for(int i=0;i<100;i++)
		{
			URL url  = new URL("http://yzk-pc:8888/myweb5/user?action=registerSubmit&username=aaa"+i+"&password=123&password2=123&yzm=aaa");
			InputStream stream = url.openStream();
			InputStreamReader reader =new InputStreamReader(stream);
			BufferedReader buffReader  = new BufferedReader(reader);
			buffReader.readLine();
			buffReader.close();
			reader.close();
			stream.close();
		}
	}

}

Session原理

1.Session和Cookie的关系:通过查看Http报文发现,Cookie中放了一个JSESSIONID,服务器中保存JSESSIONID和数据的对应关系。

2.自己实现:

UUID算法简介:根据网卡mac地址、系统时间、CPU时钟周期等算出来的值,这个值在同一台电脑上多次调用不会产生重复的值,在不同电脑的同一时刻调用也不会重复,可以保证“全球唯一”。UUID.randomUUID() 。

在服务器中生成UUID(SessionId)到Cookie中,然后在服务器中建立一个以UUID为key、value为UserName的HashMap。备注。

3.(*)浏览器的“隐私模式/小号模式”;(Chrome是隐身模式),不共享Cookie

直接关闭浏览器,然后打开浏览器重新登录,之前的Session还存在。

 

注意:Session和Cookie的关系:Cookie中放着一个JSessionid,服务器端通过JSessionid对应服务器端的“储存空间”(可能是内存或者硬盘)。

 

【模拟Session】

 

【MySession.java】

package com.rupeng.myweb5;

import java.util.HashMap;
import java.util.UUID;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class MySession
{
	//以MSessionId为key,Session键值对为value的键值对
	private static HashMap<String, HashMap<String,String>> map =new HashMap<String, HashMap<String,String>>();
	
	private HttpServletRequest req;
	private HttpServletResponse resp;
	private String mSessionId = null;
	public MySession(HttpServletRequest req,HttpServletResponse resp)
	{
		this.req = req;
		this.resp = resp;
		
		//到请求的浏览器端Cookie中查询是否有名字为MSessionId的Cookie
		Cookie[] cookies = req.getCookies();
		if(cookies!=null)
		{
			for(Cookie cookie : cookies)
			{
				if(cookie.getName().equals("MSessionId"))
				{
					mSessionId = cookie.getValue();
				}
			}
		}
		
		//如果没有,则说明没有创立对应的Session
		if(mSessionId==null)
		{
			mSessionId = UUID.randomUUID().toString();//创建一个唯一字符串
			
			//就是存放Session多个数据的Map
			HashMap<String, String> dataMap = new HashMap<String, String>();
			map.put(mSessionId, dataMap);
			
			//通过Response让浏览器把MSessionId存到Cookie中
			Cookie cookie = new Cookie("MSessionId", mSessionId);
			resp.addCookie(cookie);
		}
	}
	
	public void setAttribute(String name,String value)
	{
		HashMap<String, String> dataMap = map.get(mSessionId);
		dataMap.put(name, value);
	}
	
	public String getAttribute(String name)
	{
		HashMap<String, String> dataMap = map.get(mSessionId);
		return dataMap.get(name);
	}
}

【MYSessionServlet.java】

package com.rupeng.myweb5;

import java.io.IOException;

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

public class MYSessionServlet extends HttpServlet
{
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException
	{
		resp.setCharacterEncoding("UTF-8");
		resp.setContentType("text/html;charset=UTF-8");
		String action = req.getParameter("action");
		MySession session = new MySession(req, resp);
		if(action.equals("read"))
		{
			String un =  session.getAttribute("UserName");
			String yzm = session.getAttribute("yzm");
			
			resp.getWriter().println("un="+un+";yzm="+yzm);
		}
		else if(action.equals("write"))
		{
			session.setAttribute("UserName", "hahaa");
			session.setAttribute("yzm", "aaccee");
		}
	}
}

【UUIDTest.java】

</pre><pre name="code" class="java">package com.rupeng.myweb5;

import java.util.UUID;

public class UUIDTest
{

	/**
	 * @param args
	 */
	public static void main(String[] args)
	{
		for(int i=0;i<100;i++)
		{
		UUID id1= UUID.randomUUID();//生成一个全球唯一的不会重复的字符串
		String s1 = id1.toString();
		System.out.println(s1);
		}
	}

}

【MySessoin1.jsp】

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@page import="com.rupeng.myweb5.MySession"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
	MySession ss = new MySession(request,response);
	String un = ss.getAttribute("UserName");
	out.print(un);
%>
</body>
</html>




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值