JavaWeb-06会话及其会话技术

目录

一.Cookie(保存在用户端)

1.什么是Cookie

 使用步骤:

 2.cookie机制

 3.cookie属性项

二.[案例]显示用户上次访问时间 

 1.通过cookie保存用户上次访问时间

 三.Session(保存在服务端)

扫描二维码关注公众号,回复: 13267311 查看本文章

1.什么是Session

 2.Session机制

3.Session属性项 

四.[案例]实现购物车

​​五、如何重写URL

六.[案例]实现用户登录

Cookie与Session主要有如下区别:


一.Cookie(保存在用户端)

1.什么是Cookie

​ Cookie(s)实际上是一个小型文本文件,信息内容以key-value的形式存在.Cookie就像是商城的会员卡,当用户通过浏览器访问网站时,网站服务器可以将一些必要信息保存在cookie中,通过response对象返回给浏览器,浏览器会保存在本地,在下一次浏览改网站时,就会把这些cookie信息一同发送给该web服务器,web服务器就可以根据cookie中的信息来做出响应.(实现判断用户身份)

 使用步骤:


            1. 创建Cookie对象,绑定数据
                * new Cookie(String name, String value) 
            2. 发送Cookie对象
                * response.addCookie(Cookie cookie) 
            3. 获取Cookie,拿到数据
                * Cookie[]  request.getCookies() 
 

 2.cookie机制

当用户第一次访问并登陆一个网站的时候,cookie的设置以及发送会经历以下4个步骤:

客户端发送一个请求到服务器 --》 服务器发送一个HttpResponse响应到客户端,其中包含Set-Cookie的头部 --》 客户端保存cookie,之后向服务器发送请求时,HttpRequest请求中会包含一个Cookie的头部 --》服务器返回响应数据

 3.cookie属性项

二.[案例]显示用户上次访问时间 

 1.通过cookie保存用户上次访问时间

package cn.itcast.chapter05.cookie.example;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
@WebServlet("/LastAccessServlet")
public class LastAccessServlet extends HttpServlet {
   private static final long serialVersionUID = 1L;
   public void doGet(HttpServletRequest request, 
	                        HttpServletResponse response)
				throws ServletException, IOException {
			// 指定服务器输出内容的编码方式UTF-8,防止发生乱码
			response.setContentType("text/html;charset=utf-8");
			String lastAccessTime = null;
	         // 获取所有的cookie,并将这些cookie存放在数组中
			Cookie[] cookies = request.getCookies();
			// 遍历cookies数组
			for (int i = 0; cookies != null && i < cookies.length; i++) {
				if ("lastAccess".equals(cookies[i].getName())) {
					// 如果cookie的名称为lastAccess,则获取该cookie的值
					lastAccessTime = cookies[i].getValue();
				
				}
			}
			// 判断是否存在名称为lastAccess的cookie
			if (lastAccessTime == null) {
				response.getWriter().print("您是首次访问本站!!!");
			} else {
			     response.getWriter().print("您上次的访问时间是: " 
	                           + lastAccessTime);//把上次的时间显示到浏览完
			}
			// 创建cookie,将当前时间作为cookie的值发送给客户端
			String time=String.format("%tF%<tF", new Date());
			Cookie cookie = new Cookie("lastAccess",time);
			Cookie cookie1 = new Cookie("dashujv","2004");
			response.addCookie(cookie);
			response.addCookie(cookie1);
			
		}
	    public void doPost(HttpServletRequest req, HttpServletResponse resp)
				throws ServletException, IOException {
			this.doPost(req, resp);
		}
	}

配置映射信息,查看运行效果

注:LastAccessServlet向浏览器发送了保存用户访问时间的Cookie信息

再次访问

 

第三次访问

 

注:没有显示访问时间,说明之前浏览器存放的Cookie信息被删除。是因为在默认情况下,Cookie对象的Max-Age属性的值是-1(即浏览器关闭,删除这个cookie对象)

通过setMaxAge()方法进行设置让cookie对象在客户端有较长的存活时间,如设置有效时间为1小时

cookie.setMaxAge(60*60);

总结:

 1. 一次可不可以发送多个cookie?
            * 可以,可创建多个Cookie对象,使用response调用多次addCookie方法发送cookie即可。
        2. cookie在浏览器中的保存时间?
            1. 默认情况下,当浏览器关闭后,Cookie数据被销毁
            2. 持久化存储:
                * setMaxAge(int seconds)
                    1. 正数:持久化存储。将Cookie数据写到硬盘的文件中。取决于时间设置
                    2. 负数:默认值
                    3. 零:删除cookie信息
        3. cookie中文问题
            * 在tomcat 8 之前 cookie中不能直接存储中文数据。
                * 需要将中文数据转码---一般采用URL编码(%E3)
            * 在tomcat 8 之后,cookie支持中文数据。特殊字符不支持,建议使用URL编码存储,解码解析
        4. cookie在web项目中共享问题
            1. 同一个tomcat服务器间多个web项目cookie共享问题
                * 默认情况下cookie不能共享
                * setPath(String path):设置cookie的获取范围。
                    默认情况下,设置当前的虚拟目录
                    * 如果要共享,则可以将path设置为"/"
            2. 不同的tomcat服务器间多个web项目cookie共享问题
                    * setDomain(String path):如果设置一级域名相同,那么多个服务器之间cookie可以共享
                    * setDomain(".baidu.com"),那么tieba.baidu.com和news.baidu.com中cookie可以共享            
    5. Cookie的特点和作用
        * 特点:
            1. cookie存储数据在客户端浏览器
            2. 浏览器对于单个cookie的大小有限制(4kb)以及对
            3. 同一个域名下的总cookie数量也有限制(20个)
        * 作用:
            1. cookie一般用于存储少 的不太重要的数据(因为不安全)
            2. 在不登录的情况下,完成服务器对客户端的身份识别

  三.Session(保存在服务端)

1.什么是Session

 获取HttpSession对象:           

 HttpSession session = request.getSession();

session被称为"会话控制". 会话指的是从用户打开浏览器访问一个网站开始,无论在这个网站中访问了多少页面,点击了多少链接,都属于同一个会话。 直到该用户关闭浏览器为止,都属于同一个会话。session同样是用于保存信息,但是不同于cookie对用户可见及存储限制,session是保存在服务端,对用户不可见,但是同样可以实现在同一站点中共享信息的功能(通常共享的是用户登陆信息等…)

 2.Session机制

用户访问服务器—>服务器判断是否是第一次连接—>第一次连接则创建一个新的session,期中包含一个唯一的ID值—>该ID值会以cookie信息的形式(key=jsessionid, value=ID)返回给用户端保存,用以下次辨别用户身份—>用户再次访问,服务器就可以判断用户已经访问过

3.Session属性项 

一般来说,在项目使用中都会配置Session超时时间,如果不配置,则默认值为30分钟,即用户不操作30分钟以后,Session就会失效,此时用户就需要重新登录系统。

Session超时时间的配置主要的项目的web.xml中进行配置,如下:

<session-config>
     <session-timeout>30</session-timeout>  //设置为0或一个负数,会话永不超时
</session-config>

 注:通过invalidate()方法强制使会话失效

总结:

 1. 当客户端关闭后,服务器不关闭,两次获取session是否为同一个?
            * 默认情况下。不是。
            * 如果需要相同,则可以创建Cookie,键为JSESSIONID,设置最大存活时间,让cookie持久化保存。
                 Cookie c = new Cookie("JSESSIONID",session.getId());
                 c.setMaxAge(60*60);
                 response.addCookie(c);

        2. 客户端不关闭,服务器关闭后,两次获取的session是同一个吗?
            * 不是同一个;相同的话要必须确保数据不丢失。tomcat自动完成以下工作
                * session的钝化:序列化过程
                    * 在服务器正常关闭之前,将session对象系列化到硬盘上
                * session的活化:反序列化过程
                    * 在服务器启动后,将session文件转化为内存中的session对象即可。          
        3. session什么时候被销毁?
            1. 服务器关闭
            2. session对象调用invalidate() 。
            3. session默认失效时间 30分钟
                选择性配置修改    
                <session-config>
                    <session-timeout>30</session-timeout>
                </session-config>
     5. session的特点
         1. session用于存储一次会话的多次请求的数据,存在服务器端
         2. session可以存储任意类型,任意大小的数据

四.[案例]实现购物车

五、如何重写URL

 1.对ListBookServlet 类中 for 循环内的代码进行修改,将请求访问的路径改为URL重写

for(Book b:books) {
			String name=b.getName();
			String id=b.getId();
			String url="<a href='purchares?id="+id+"'>购买记录</a>";
			out.print("图书名称:"+name+" "+url+"<br/><br/>");
			System.out.println("图书名称:"+name+" "+url+"<br/><br/>");
		}

注:在重写URL,要通过getsession()获取session对象

2.修改purchaservlet

String id=request.getParameter("id");
		System.out.println("id : "+id);
		if(id==null) {
			response.sendRedirect("list");
			return;
		}

3.重启

 注:无论浏览器是否支持Cookie,当用户第1次访问程序时,由于服务器不知道用户的浏览器是否支持Cookie,在第1次响应的页面中都会对URL地址进行重写,如果用户浏览器支持Cookie,那么在后续访问中都会使用Cookie的请求头字段将Session标识号传递给服务器。由此,服务器判断出该浏览器支持Cookie,以后不再对URL进行重写。如果浏览器的头信息中不包含Cookie请求头字段,那么在后续的每个响应中都需对URL进行重写。另外,为了避免其他网站的某些功能无法正常使用,通常情况下,需要启用Cookie的功能。

六.[案例]实现用户登录

网站首界面

package cn.itcast.chapter05.session.example02;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.*;
public class IndexServlet extends HttpServlet {
public void doGet(HttpServletRequest request,HttpServletResponse response)
			throws ServletException, IOException {
          // 解决乱码问题
		response.setContentType("text/html;charset=utf-8");
         // 创建或者获取保存用户信息的Session对象
		HttpSession session = request.getSession();
		User user = (User) session.getAttribute("user");
		if (user == null) {
			response.getWriter().print(
			"您还没有登录,请<a href='/chapter05/login.html'>登录</a>");
		} else {
            response.getWriter().print("您已登录,欢迎你," + user.getUsername() + "!");
			response.getWriter().print(
					"<a href='/chapter05/LogoutServlet'>退出</a>");
			// 创建Cookie存放Session的标识号
			Cookie cookie = new Cookie("JSESSIONID", session.getId());
			cookie.setMaxAge(60 * 30);
			cookie.setPath("/chapter05");
			response.addCookie(cookie);
		}
	}
	public void doPost(HttpServletRequest request, 
                           HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}
}

登录成功界面

public void doGet(HttpServletRequest request, HttpServletResponse response)
		throws ServletException, IOException {
	response.setContentType("text/html;charset=utf-8");
		String username = request.getParameter("username");
	String password = request.getParameter("password");
	PrintWriter pw = response.getWriter();
        //假设正确的用户名 是Lily 密码是123
		if (("LiLy").equals(username) && ("123").equals(password)) {
		User user = new User();
			user.setUsername(username);
		user.setPassword(password);
	request.getSession().setAttribute("user", user);
			response.sendRedirect("/chapter05/IndexServlet");
	} else {
		pw.write("用户名或密码错误,登录失败");
		}
	}

用户注销

public class LogoutServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
		throws ServletException, IOException {
     // 将Session对象中的User对象移除
		request.getSession().removeAttribute("user");
		response.sendRedirect("/chapter05/IndexServlet");
	}
	public void doPost(HttpServletRequest request, 
       HttpServletResponse response)throws ServletException, IOException {
		doGet(request, response);
	}
}

 验证码设置

public void doGet(HttpServletRequest request,HttpServletResponseresponse)throwsServletException, IOException {
			response.setContentType("text/html;charset=utf-8");
			String username = request.getParameter("username");
			String password = request.getParameter("password");
			String checkCode = request.getParameter("check_code");
			String savedCode = (String) request.getSession().getAttribute(
					"check_code");
			PrintWriter pw = response.getWriter();
			if (("Lily").equals(username) && ("123").equals(password)
					&& checkCode.equals(savedCode)) {
				User user = new User();
				user.setUsername(username);
				user.setPassword(password);
				request.getSession().setAttribute("user", user);
				response.sendRedirect("/chapter05/IndexServlet");
			} else if (checkCode.equals(savedCode)) {
				pw.write("用户名或密码错误,登录失败");
			} else {
				pw.write("验证码错误");
			}
		}	

验证码图片

 import java.io.*;
 import javax.servlet.*;
 import javax.servlet.http.*;
 import java.awt.*;
 import java.awt.image.*;
 import javax.imageio.ImageIO;
 public class CheckServlet extends HttpServlet
 {
 	private static int WIDTH = 60; //验证码图片宽度
 	private static int HEIGHT = 20; //验证码图片高度
 public void doGet(HttpServletRequest request,HttpServletResponse response) 
 			throws ServletException,IOException{		
 		HttpSession session = request.getSession();
 		response.setContentType("image/jpeg");
 		ServletOutputStream sos = response.getOutputStream();
 		//设置浏览器不要缓存此图片
 		response.setHeader("Pragma","No-cache");
 		response.setHeader("Cache-Control","no-cache");
 		response.setDateHeader("Expires", 0);
 		//创建内存图象并获得其图形上下文
 		BufferedImage image = 
 			new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB); 
 		Graphics g = image.getGraphics();
 		//产生随机的认证码
 		char [] rands = generateCheckCode();
 		//产生图像
 		drawBackground(g);
 		drawRands(g,rands);
 		//结束图像的绘制过程,完成图像
 		g.dispose();
 		//将图像输出到客户端
 		ByteArrayOutputStream bos = new ByteArrayOutputStream();
 		ImageIO.write(image, "JPEG", bos);
 		byte [] buf = bos.toByteArray();
 		response.setContentLength(buf.length);
 		//下面的语句也可写成:bos.writeTo(sos);
 		sos.write(buf);
 		bos.close();
 		sos.close();
 		//将当前验证码存入到Session中
 		session.setAttribute("check_code",new String(rands));
 		//直接使用下面的代码将有问题,Session对象必须在提交响应前获得
 	//request.getSession().setAttribute("check_code",new String(rands));
 	}
        //生成一个4字符的验证码
 	private char [] generateCheckCode()
 	{
 		//定义验证码的字符表
 		String chars = "0123456789abcdefghijklmnopqrstuvwxyz";
 		char [] rands = new char[4];
 		for(int i=0; i<4; i++)
 		{
 			int rand = (int)(Math.random() * 36);
 			rands[i] = chars.charAt(rand);
 		}
 		return rands;
 	}
 	private void drawRands(Graphics g , char [] rands)
 	{
 		g.setColor(Color.BLACK);
 		g.setFont(new Font(null,Font.ITALIC|Font.BOLD,18));
 		//在不同的高度上输出验证码的每个字符		
 		g.drawString("" + rands[0],1,17);
 		g.drawString("" + rands[1],16,15);
 		g.drawString("" + rands[2],31,18);
 		g.drawString("" + rands[3],46,16);
 		System.out.println(rands);
 	}
 	private void drawBackground(Graphics g)
 	{
  		//画背景
 		g.setColor(new Color(0xDCDCDC));
 		g.fillRect(0, 0, WIDTH, HEIGHT);
 		//随机产生120个干扰点
 		for(int i=0; i<120; i++)
 		{
 			int x = (int)(Math.random() * WIDTH);
 			int y = (int)(Math.random() * HEIGHT);
 			int red = (int)(Math.random() * 255);
 			int green = (int)(Math.random() * 255);
 			int blue = (int)(Math.random() * 255);
 			g.setColor(new Color(red,green,blue));		
 			g.drawOval(x,y,1,0);
 		}
 	}
 }

 

 

 

 


Cookie与Session主要有如下区别:

1)Cookie和HttpSession是保存会话相关数据的技术,其中Cookie将信息存储在浏览器端是客户端技术,Session将数据保存在服务器端是服务器端技术

2)Cookie是基于HTTP协议中的Set-Cookie响应头和Cookie请求头进行工作的

3)默认情况下HttpSession是基于一个名称为JSESSIONID 的特殊Cookie工作的

4)浏览器对Cookie具有严格的限制,一个网站能在浏览器中保存多少Cookie是有限制的

5)HttpSession默认是基于Cookie运作的


猜你喜欢

转载自blog.csdn.net/qq_55694317/article/details/121171044
今日推荐