cookie简介:
cookie来源:HTTP协议是一种无状态协议,即本次请求与下次请求无关系。而在不同请求时需要进行数据传递,需要一种可以进行请求间数据传递的会话跟踪技术,cookie因此而生。
cookie机制:用户提交第一次请求后,由服务器生成(是一种保存在客户端的信息载体技术,cookie可被清空,可失效),并将其封装至响应头,以响应形式发给客户端,
客户端收到响应后将cookie保存在客户端。当客户端再次发送同类请求后,在请求中会携带保存在客户端的cookie数据发送给服务端。由服务器对会话进行跟踪。
cookie属性:属于web技术,非javaweb专项技术;由若干键值对构成cookie("name","value");
注意:同类请求:http://localhost:8080/project/xxx/ccc/some 同类请求即资源路径相同的请求 http://localhost:8080/project/xxx/ccc 资源路径,(它在web.xml的
只要你写的 http://localhost:8080/project/xxx/ccc 路径相同,则是同类路径。
javaWeb中的cookie:
1,javaWeb中的cookie属于一个类。
2,创建cookie:Cookie(String name,String value);例:Cookie cookie = new Cookie("student","zyz");
3,响应中添加cookie:response.addCookie("");响应中的方法。例:response.addCookie(cookie );
4,指定cookie绑定路径:Cookie.setPath(request.getContextPath()+"xxx/ooo/aaa");
5,设置cookie有效期,此值为整数,单位秒:
cookie.setMaxAge(60*60);有效期一小时。 //该设置值 > 0,表示cookie存放在客户端硬盘。
该设置值 < 0,与不设置一样,将cookie存放在浏览器缓存。会话结束时cookie消失,即浏览器关了就没了。
该设置值 = 0,表示cookie一生成就马上失效。
6,获取请求中的cookie:
Cookie[ ] cookies = request.getCookies();
7,遍历cookie:
for(Cookie cookie : cookies) {
System.out.println(cookie.getName() + "===" + cookie.getValue());
if(cookies.getNmae().equals("student") && cookie.getValue().equals("zyz")) {
//你需要的操作
}else if {
//你需要的操作
}
}
cookie用法:创建cookie (some文件),响应cookie ;获取cookie(other文件),再进行你需要的操作。 两者在同路径下。
cookie禁用:在浏览器中可以设置禁用cookie,去选“接受来自站点的cookie”禁用的是自己客户端的cookie 。cookie被禁用后cookie仍然可以生成,但request无法获取cookie,很多网站也将无法访问。
javaWeb中的session (javaWeb开发中,Session是以javax.servlet.http.HttpSession的接口对象形式出现)
session的三个域书性空间对比:
1,ServletContext,置入其中的域属性是整个应用范围的,可以完成跨会话共享数据。应用启动时创建,域属性空间创建,不删除则一直存在整个应用。空间很长。
2,HttpSession,置入其中的域属性是会话范围的,可以完成跨请求共享数据。
3,HrrpServletRequest,置入其中的域属性是请求范围的,可以跨servlet共享数据,但这写servlet必须在同一请求中。生命周期很短,域属性空间也很短。
三者使用原则:保证需求前提下,优先使用最小,节省服务器内存,保证数据安全性。ServletContext > HttpSession > HrrpServletRequest,
session简介
来源:也是web开发的会话跟踪技术,同样是服务器生成。不同在cookie是将会话状态保存在客户端,session则是将会话状态保存在服务端。
什么是会话:用户打开浏览器,发出第一次请求,到浏览器关闭,表示一次会话完成。
HttpSession的三个方法:
public void setAttribute(String name,Object value) {} 用于向session的域属性空间中放入指定名称,指定值的域属性。
public void getAttribute(String name) {} 用于从session的域属性空间中读取指定名称的域属性。
public void removeAttribute(String name) {} 用于向session的域属性空间中删除指定名称的域属性。
在session与空间中存放数据:
首先要获取了session对象才能存放数据。 HttpSession session=request.getSession();
在此注意获取session对象要使用的方法,方法有两个,特性如下:
1,getSession();无参
2,getSession(true/false);
true:如果有已创建的session就用已创建的,若没有就新建
flase:如果有已创建的session就用已创建的,若没有就不新建,返回null
一般情况下:1,向session域空间中写入数据用getSession(true),即getSession();方法。因为要创建session对象存储数据。
2,而从session域空间中读数据则用getSession(false);方法。 读取数据是要读取先前创建的session对象中的数据,若选用true就会新建session对象,那session中就没有数据了。
现在要在session域中写入属性。但是现没有session,所以要创建就getSession(true);true可以不写。
session的工作机制
1,写入session列表:请求到达时将jsessionID和session对象写到session列表中。
(服务器对当前应用中的session以Map形式管理,Map称为session列表。Map的key是一个32位随机串即jsessionID,value则为session对象的引用,
用户首次提交请求时,服务端servlet中执行到request.getSession()方法后自动生成Map.Entry对象,key据算法生成jsessionID,value则时新创建的Httosession对象;)
2,服务器生成并发送Cookie:在将session信息写入session列表后,系统还会自动将jsessionID作为name,32位随机串作为value,以Cookie的形式存放到响应头中,并随即响应,将cookie发送至客户端;
3,客户端接收并发送客户端:客户端接收到cookie后将其存入浏览器缓存,即客户端浏览器不关闭,浏览器中cookie不消失。当用户第二次请求时,会将缓存中的cookie伴随请求头部信息一块发送都服务端。
4,送session列表中查找:服务端从请求中读取到客户发送的cookie,根据cookie的jsessionID的值,从Map中查找相应key所对应的value,即session对象,再对session对象的域属性进行读写操作。
总结:servlet中获取session,在session中写入属性,底层服务器检测到getSession后生成随机字符串,再创建session对象,然后以32位随机字符串为key,以session对象为value放入session列表中即Map中,
用户首次请求servlet,服务器再放入session列表后将32为随机串包装成cookie发送给客户端浏览器(cookie的name==jsessionID,value==32位随机串),客户端浏览器接收cookie将其保存再缓存中。
当再次客户端请求读取数据时,会将浏览器缓存中cookie里的jsessionID放到请求头部信息中发送给服务器,服务器拿到jsessionID后就去session列表中查找,
找到后key后就找到了key所对应的value(存放有域属性的session),然后从中读数据。
session失效
在web.xml中可以通过
若未到超时时限,HttpSession中方法,invalide()可实现失效;
cookie禁用
首先生成随机串,写入session列表,随机串包装成cookie==jsessionID,放入响应头,发送客户端,这是服务端的cookie。客户端接收cookie放入缓存,客户端第二次请求时会将缓存中的cookie发送给服务器,
好的,问题来了,如果客户端禁用了cookie,那服务端发来的带有cookie的响应,客户端不会接收,不接收客户端又提交一次请求,提交给服务端的这个请求没有jsessionID大的cookie,服务端会将其看成第一次请求,
就会再次生成随机串,包装成cookie,生成session,发送给客户端,客户端因为session禁用,又不会接收,再一次请求服务端又看成第一次请求,就成循环,问题就大了。
问题:那么cookie禁用了就不能是实现会话跟踪了吗?session就不能用了吗?
能用。 禁用cookie,客户端不接收服务端发送过来的cookie。但是会生成jsessionID,根据此次生成的jsessionID,再一次提交请求,session 还是会变,但是不会再重新生成新的cookie(也就时服务器生成32位随机数)。
//例:
http://localhost:8080/sessionandcookie/SomeSession:jsessionid=881CDDC1766E28391FS3E3E3B16669(这是上次会话生成的jsessionID,记录下来,根据这个地址进去)
根据这个带有jsessionID的地址进去提交请求,第一次sessionID是很变,但是不会生成cookie,也不会携带有jsessionID。
再一次刷新,会发现session也不会变,而后刷新多少次都不会变。因为根据jsessionID已经实现了会话跟踪。
假设: 如果上一个人进入网页或者某宝购物后,关闭浏览器走了,我们获取了他网页的jsessionID,那我们就能进入本次会话,简单说就是进入他某宝账户,修改某些东西也是可以的。
但是这也就牵扯但一个问题。会话什么时候结束?关闭了浏览器那算不算会话结束?
什么是会话:
就客户端而言:用户打开浏览器,发出第一次请求,到浏览器关闭,表示一次会话完成。
服务端:
第一次请求开始,session失效时候会话结束。
关闭浏览器后服务器的session依旧没有失效,此次会话依旧可以进入。所以在使用非私人手机或电脑时要退出账户,数据解绑,session失效。
cookie禁用后重定向时的session跟踪
上面谈到,cookie禁用后的session跟踪需要jsessionID进行跟踪,但是这也意味着jsessionID暴露在地址栏,这会跟危险。
那怎么才能不暴露jsessionID,而又能在cookie被禁用的情况下进行会话跟踪呢?在此引入重定向。
例1:
RedirectServlet_1文件
HttoSession session = request.getSession(); //获取session对象
session.setAttribute("user" , "student"); //写入数据
System.out.println("RedirectServlet_1 session =" +session);
respone.sendRedirect(request.getContextPath() + "/RedirectServlet_2");
RedirectServlet_2
HttoSession session = request.getSession(false); //获取session对象
System.out.print("RedirectServlet_2 : session = " + session);
//从session中获取指定属性
String user = null;
if(session != null) {
user = (String ) session.getAttribute("user");
}
PrintWriter out = respone.getWriter();
out.println("RedirectServlet_2 : user = " + user);
这个例子是cookie被禁用后使用重定向失败的例子,结果为:
RedirectServlet_2 : user = null
响应头信息为:
http://localhost:/cookieandsession/RedirectServlet_1 //响应有cookie(cookie==jsessionID),响应有信息session;
http://localhost:/cookieandsession/RedirectServlet_2 //响应没有cookie(cookie==jsessionID),响应为null;
重定向时候又重新提交了一次请求;
这个案例失败了,没有跟踪到会话;
例2:
RedirectServlet_1文件
HttoSession session = request.getSession(); //获取session对象
session.setAttribute("user" , "student"); //写入数据
System.out.println("RedirectServlet_1 session =" +session);
//加上这个方法
String url = request.getContextPath() + "/RedirectServlet_2";
url = response.encodeRedirectURL(url); //解决cookie禁用后session的跟踪问题;
response.sendRedirect(url);
这个例子是cookie被禁用后使用重定向成功的例子,结果为:
RedirectServlet_2 : user = null
响应头信息为:
http://localhost:/cookieandsession/RedirectServlet_1 //响应有cookie(cookie==jsessionID),响应有信息session;
http://localhost:/cookieandsession/RedirectServlet_2 //响应有cookie(cookie==jsessionID),响应为student;
此次重定向的请求cookie的jsessionID一样。
如果cookie没有被禁用,结果也是如此。只要加了这个方法不管cookie是否被禁用session都可以被禁用。但是最好不要禁用cookie,禁用后看似安全其实不安全。
cookie被禁用后进行session跟踪,jsessionID也就暴露了,并不安全。
cookie禁用后非重定向的session跟踪
超链接URL的重写:
HttpServletResponse具有一个方法 encodeURL(),可以完成对类似超链接的非重定向页面跳转的URL重写,即在其具体路径后会自动添加jsessionID。
cookie没有被禁用时
例1:
RedirectServlet_1文件
HttoSession session = request.getSession(); //获取session对象
session.setAttribute("user" , "student"); //写入数据
respone.setContentType("/text/html;charset = utf -8");
PrintWriter out = respone.getWriter();
out.println("跳转到RedirectServlet_2");
省略RedirectServlet_2,与上一致
输出结果:RedirectServlet_2 :user: = student
cookie被禁用时
没有使用encode URL();方法
输出结果:RedirectServlet_2 :user: =null
使用encode URL();方法
例1:
RedirectServlet_1文件
HttoSession session = request.getSession(); //获取session对象
session.setAttribute("user" , "student"); //写入数据
respone.setContentType("/text/html;charset = utf -8");
PrintWriter out = respone.getWriter();
String url = "RedirectServlet_2";
//解决cookie禁用后,非重定向时的session跟踪问题;
url = response.encodeURL(url);
out.println("跳转到RedirectServlet_2");
省略RedirectServlet_2,与上一致
输出结果:RedirectServlet_2 :user: = student
以上为学习b站大佬后的笔记,大佬写的很详尽,再次附上学习地址 https://www.bilibili.com/video/BV1s4411z7zq