欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

JAVA WEB---Cookie+Session

程序员文章站 2022-03-11 16:36:43
...

1.Cookie

package com.hxuner.web;

import java.io.IOException;
import java.util.Date;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/*
 * 1.会话的概念:
 * 				-------- 从用户打开浏览器,对服务器进行多次请求,到关闭浏览器,称为一次会话--------------
 * 				 用户为了实现一个目标,而对服务器进行一系列的访问,称为一次会话
 * 
 * 2.会话的挑战
 * 				http协议是一次请求一次应答后断开连接,每次请求对于服务器来说都是一次新的请求
 * 				但是,在会话过程中,会产生一个临时数据(会话状态),比如用户登录的状态,用户添加的购物车等等
 * 				如何存储这些数据,实现整个会话期间的数据共享,就是一个挑战
 * 
 *   会话技术就是会话的挑战的解决方案
 * 
 */

/*
 * 	Cookie
 * 		1.概念
 * 			Cookie将用户产生的会话数据保存在客户端浏览器上,是浏览器解决方案
 * 
 * 			服务器收到请求->set-cookie应答头->将数据返回给浏览器,浏览器收到cookie后,会存储在浏览器的内存/硬盘上
 * 			浏览器再次发送请求时->将符合条件的Cookie以请求头的形式->发送给服务器
 * 			因此服务器可以在收到请求后,拿到之前在浏览器保存的会话数据.
 *      
 *      
 *      2.原生API
 *      		response.setHeader("set-cookie","name=value")  response设置cookie
 *      		request.getHeader("cookie")					   request获取cookie
 * 
 */
//浏览器输入http://localhost/day012JavaWebCookie/servlet/Cookie01
public class Cookie01 extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		//处理乱码
		response.setContentType("text/html;charset=utf-8");
		
		//1.接受用户请求,获取当前时间->本次访问时间
		String dateStr=new Date().toLocaleString();
		
		//2.通过cookie将本次访问时间返回给浏览器
		//----------response.setHeader("set-cookie", "time="+dateStr);--------response设置cookie-----------------------------
		response.setHeader("set-cookie", "time="+dateStr);
		//response.addHeader("set-cookie", "age=18");   //添加数据要addHeader(),不然相同的key,值会覆盖,只留一份
		
		
		//3.获取用户传来的Cookie中携带的上次访问时间
		//---------request.getHeader("cookie");----------------------request获取cookie--------------------------
		String lasttime=request.getHeader("cookie");
		
		
		//4.给用户应答,你上次访问的时间是...
		if(lasttime==null){
			//是第一次访问
			response.getWriter().write("你是第一次访问");
		}else{
			response.getWriter().write("你上次访问时间"+lasttime.split("=")[1]);  //lasttime="time=datestr"  =分隔为两部分time=和datestr 取第二个
		}
	}

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

}
package com.hxuner.web;

import java.io.IOException;
import java.util.Date;

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

/*
 * sun公司提供操作cookie的API
 * 			Cookie cookie=new Cookie(name,value);   创建cookie对象
 * 			response.addCookie(cookie);				cookie对象存入response
 * 			Cookie[] cs=request.getCookies();		 获取cookie对象
 * 
 * 
 * 			设置Cookie的有效时间	
 * 								cookie.setMaxAge(xxs);
 * 								如果不设定时间,Cookie默认是会话级别的,存储在浏览器的内存中,浏览器关闭则Cookie被销毁
 * 								如果设定了时间,Cookie会被持久化到硬盘上,不会随浏览器的关闭而销毁
 * 
 * 			设置Cookie的路径
 * 								cookie.setPath()
 * 								如果浏览器请求的domain+path与当前Cookie的domain+path一致,或者是其子路径,则会自动携带当前Cookie
 * 			
 * 			设置Cookie的域名
 * 								cookie.setDomain
 * 								一般不使用,以免被浏览器拒绝
 * 
 * 			删除Cookie
 * 								Cookie cookie=new Cookie("time","");           //name相同
								cookie.setPath(request.getContextPath()+"/");  //path相同,domain设置无用,被浏览器拒绝
								cookie.setMaxAge(0);						   //同一个cookie,后发的cookie覆盖之前的,存活时间0秒
								response.addCookie(cookie);
  
								如果想要删除一个Cookie,向浏览器发送一个新的同name,同path,同domain的Cookie,只需要将Cookie的maxAge设置为0
								由于浏览器是根据 name+path+domain 来区分Cookie的, 所以当两个cookie的上述条件相同时, 浏览器就会认为是同一个Cookie, 
								那么后发的Cookie会覆盖之前的, 而后发的Cookie的存活时间为0, 所以浏览器收到后也会立即删除!!
		
		    注意:
		    	1. Cookie中不能携带中文字符,需要使用URLEncoder.encode(str,charset),将中文字符转成对应的charset的表示		(服务器端)
		    	2. 在页面上,为了正常显示Cookie中携带的中文,必须使用URLDecoder.decode(str,charset),将字符集的表示转为中文	 (JSP)
		    	3. 一个浏览器可以存储多个站点发来的Cookie,一个站点也可以给多个浏览器发送Cookie
		    	4. 一个浏览器最多存储300个Cookie,每个站点20个,每个Cookie的大小上限是4kb
		
 */
//浏览器输入http://localhost/day012JavaWebCookie/servlet/Cookie02
public class Cookie02 extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		//演示sun公司提供的API
		//处理应答乱码
		response.setContentType("text/html;charset=utf-8");
		//1.获取当前时间
		String dateStr=new Date().toLocaleString();
		
		//2.通过cookie将本次访问时间返回给浏览器
		//Sun公司提供了Cookie类,代表了一个Cookie信息
		Cookie cookie=new Cookie("time",dateStr);    //创建Cookie对象       --------------new Cookie("time",dateStr);-----------------
		
		
		//response.setHeader("set-cookie", "time="+dateStr);等价于2,3两步
		
		//-------------------------------cookie额外的设置start------------------------------------------------------------------------
		/*	
		 	Cookie默认是会话级别的,也是存储在浏览器的内存中,浏览器关闭cookie销毁
			如果希望浏览器关闭而Cookie依旧存在,需要给Cookie设定一个有效时间
		 	对于设定了有效时间的Cookie,浏览器会将Cookie持久化到硬盘上存储
		 */
		//设定时长30天,单位s
		cookie.setMaxAge(60*60*24*30);       	 				//设置Cookie存活时间 -----------------cookie.setMaxAge()单位s----------------
		
		
		/*
		   如果浏览器请求的domain+path与当前Cookie的domain+path一致,或者是其子路径,则会自动携带当前Cookie,否则不携带cookie
		    默认情况下,cookie携带的path属性是当前Servlet的父路径,现在默认路径是http://localhost/day012JavaWebCookie/Servlet
		   如果希望 访问http://localhost/day012JavaWebCookie/ 携带数据,就要设置setPath()
		*/
		//request.getContextPath()方法返回"",则setPath不生效,需要加/
		cookie.setPath(request.getContextPath()+"/");  			//设置Cookie路径  ----------------setPath(String path);-----------------
		
		
		
		//--------浏览器标记一个cookie,通过name,path,domain组合来唯一标识同一个cookie------------
		
		
		
		//设置域名的api,不建议设定->有可能被浏览器拒绝,小网站可以仿造其他域名,浏览器认为不安全
		//cookie.setDomain(pattern);                    		//设置域名的api--------------cookie.setDomain(pattern);  -----------
		 
		//-------------------------------cookie额外的设置end-----------------------------------------------------------------------------
		
		
		
		
		//3.将Cookie存入response
		response.addCookie(cookie);				    //将Cookie对象存入response----------response.addCookie(cookie);----------------
		
		
		//4.获取用户随请求传来的Cookie
		//request.getCookies()返回用户传来的所有cookie
		Cookie[] cs=request.getCookies();          //获取所有cookie --------Cookie[] cs=request.getCookies();----------------------
		Cookie findC=null;
		if(cs!=null){
			for(Cookie c:cs){
				if("time".equals(c.getName())){    //获取cookie的名字  ----------Cookie.getName()---------------------
					findC=c;
					break;
				}
			}
		}
		if(findC!=null){
			response.getWriter().write("你上次访问的时间是"+findC.getValue());  //获取cookie的值 --------Cookie.getValue()----------
		}else{
			response.getWriter().write("你是第一次访问");
		}
	}

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

}
package com.hxuner.web;

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 Cookie03 extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		//sun公司没有提供直接删除Cookie的API
		
		
		//删除Cookie
		//如果想要删除一个Cookie,向浏览器发送一个新的同name,同path,同domain的Cookie,只需要将Cookie的maxAge设置为0
		//由于浏览器是根据 name+path+domain 来区分Cookie的, 所以当两个cookie的上述条件相同时, 浏览器就会认为是同一个Cookie, 
		//那么后发的Cookie会覆盖之前的, 而后发的Cookie的存活时间为0, 所以浏览器收到后也会立即删除!!
		
		Cookie cookie=new Cookie("time","");           //name相同
		cookie.setPath(request.getContextPath()+"/");  //path相同,domain设置无用,被浏览器拒绝
		cookie.setMaxAge(0);						   //后发的cookie覆盖之前的,存活时间0秒
		response.addCookie(cookie);
	}

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

}

2.Session

package com.hxuner.web;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/*
 * Session
 * 			概念:Session是将用户产生的会话信息存储在服务器端,是服务器端的解决方案
 *                Session是四大作用域之一,称为session作用域
 *          
 *          生命周期:
 *          		创建:用户第一次调用request.getSession()方法,会为当前用户创建一个Session对象
 *          		存活:默认在内存中存在30分钟,--------是从最后一次访问session开始算-------------
 *          	       销毁:1.默认情况      超过30分钟没有访问该session,则销毁
 *          			  
 *          			  2.自杀 	   session.invalidate()->马上销毁该session对象
 *          			  
 *          			  3.意外销毁      服务器异常关闭,所有的session会随应用的销毁而销毁
 *          			  
 *          			 4.钝化和活化  服务器正常关闭时,所有未超时的session会被序列化到tomcat/work/catalina/虚拟主机/web应用/SESSIONS.ser来保存,称为钝化
 *          						    当服务器启动时,所有钝化的session会被反序列化到内存中,继续生效,称为活化
 *         
 *          API:
 *          		和其他作用域一致
 */
public class Session01 extends HttpServlet {

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

	}

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

}
<%@ 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>
	<!-- 
		禁用Cookie的情况下使用Session
			    URL重写: 就是在传入的URL地址后拼接JSESSIOINID返回一个新的地址, 用来在禁用Cookie的情况下用url地址来携带JSESSIOINID
				
				response.encodeURL(String url);
				//--如果是普通的地址用这个方法
				response.encodeRedirectURL(String url);
				//--如果地址是用来进行重定向的,用这个方法
	 -->
	<a href="<%=response.encodeUrl("/day12/BuyServlet?prod=阿迪王皮鞋") %>">阿迪王皮鞋</a><br>
    <a href="/day12/BuyServlet?prod=蓝月河洗衣液">蓝月河洗衣液</a><br>
    <a href="/day12/BuyServlet?prod=TLC电视">TLC电视</a><br>
    <a href="<%=response.encodeUrl("/day12/PayServlet") %>">支付</a><br>   
</body>
</html>

 

package com.hxuner.web;

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;
import javax.servlet.http.HttpSession;

public class pbuyServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		//1.处理乱码
		response.setContentType("text/html;charset=utf-8");
		//2.获取请求参数
		String prod=request.getParameter("prod");
		if(prod!=null){
			//手动编解码解决get请求乱码
			prod=new String(prod.getBytes("iso8859-1"),"utf-8");
		}
		
		//3.将商品信息添加到session作用域
		//第一次调用该方法时,会为用户创建一个新的Session对象
		//后面用户多次调用该方法,该方法返回的是第一个创建的那个session对象
		HttpSession session=request.getSession();
		
		/*
		 	怎么解决浏览器关闭之后, 无法使用浏览器关闭之前的Session??
				(注意: 在访问一个jsp时, 默认一上来就会创建session!!)  
				session还在,默认存在30分钟,就是cookie销毁,而cookie的session id唯一标识session也不能标识了
				方案:让cookie活久一点
		*/
		// 服务器依靠用户携带的JSESSIONID的Cookie来查找对应的session对象,该cookie默认是会话级别,浏览器关闭则销毁
		// 没有API可以直接访问到该Cookie对象,因此可以自己重新发送一个同名的Cookie
		Cookie cookie=new Cookie("JSESSIONID", session.getId());
		cookie.setMaxAge(60*30);//30分钟
		cookie.setPath(request.getContextPath()+"/");
		response.addCookie(cookie);
				
		session.setAttribute("prod", prod);
		
		
		
		//4.给用户请求
		response.getWriter().write("恭喜您,"+prod+"已经成功添加到购物车");
		response.setHeader("refresh", "3;url="+response.encodeRedirectUrl(request.getContextPath()+"/sales.jsp"));
		/*
			禁用Cookie的情况下使用Session
			    URL重写: 就是在传入的URL地址后拼接JSESSIOINID返回一个新的地址, 用来在禁用Cookie的情况下用url地址来携带JSESSIOINID
				
				response.encodeURL(String url);
				//--如果是普通的地址用这个方法
				response.encodeRedirectURL(String url);
				//--如果地址是用来进行重定向的,用这个方法
		 */
		
	}

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

}
package com.hxuner.web;

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 payServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setContentType("text/html;charset=utf-8");
		// 从用户绑定的session作用域中获取到已添加的商品
		// req.getSession(false)->尝试获取(而不是创建)该用户绑定的session,如果该session不存在,则返回null
		HttpSession session=request.getSession(false);
		//要么无session要么session无prod商品
		if(session==null||session.getAttribute("prod")==null){
			response.getWriter().write("你还没有购买商品,3秒后跳转购买商品页面");
			response.setHeader("refresh", "3;url="+request.getContextPath()+"/sale.jsp");
		}else{
			
			response.getWriter().write("你购买的商品是"+session.getAttribute("prod")+",支付¥100");
		}
	}

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

}
package com.hxuner.web;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/*
 * Cookie和Session的区别
 * 			-------------------------------------------------------------
 * 					将会话数据存入浏览器端,是浏览器端的解决方案
 * 					优势:不占用服务器的内存空间
 * 			Cookie:		 存放的时间比较长
 * 					
 * 					劣势:可能因为用户的误操作而被删除
 * 						  用户机的防火墙级别较低,Cookie中的数据可能被盗取
 * 
 * 					需要存放较长时间,且安全性不太高的数据
 * 
 *          --------------------------------------------------------------------
 *          
 * 					将会话数据存在服务器端,是服务器端解决方案
 * 					优势:存在服务器的内存中,服务器防火墙级别高,所以安全性高	
 * 			Session:	  被误操作删除的可能性非常低
 * 					
 * 					劣势:存在时间比较短,因为会占用服务器的内存
 * 
 * 					安全性比较高的,不需要长期存放的数据,使用Session
 * 
 * 
 * 			----------------------------------------------------------------
 * 			注意:又想长时间保存数据,安全性又高,可以使用数据库
 */
public class zCookie_Session extends HttpServlet {

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

	}

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

}