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