博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
cookie与session
阅读量:2062 次
发布时间:2019-04-29

本文共 8052 字,大约阅读时间需要 26 分钟。

Cookie

简介

Cookie是HTTP协议的规范之一,它是服务器和客户端之间传输的小数据。

 首先由服务器通过响应头把Cookie传输给客户端,客户端会将Cookie保存起来。

 当客户端再次请求同一服务器时,客户端会在请求头中添加该服务器保存的Cookie,发送给服务器。

Cookie规范

Cookie通过请求头和响应头在服务器与客户端之间传输;
 Cookie大小限制在4KB之内;
一台服务器在一个客户端最多保存20个Cookie;
一个浏览器最多可以保存300个Cookie;
虽然Cookie规范是如此,但在今天,浏览器厂商的竞争异常激烈,所以多少会超出Cookie规则的限制。但也不会超出过多!

cookie的使用

我们有两种设置cookie的方法,1 通过响应头来设置cookie  2 通过response.addcookies() 方法便捷设置cookie。

让我们来看看使用代码:

public class AServlet extends HttpServlet {	public void doGet(HttpServletRequest request, HttpServletResponse response)			throws ServletException, IOException {		response.addHeader("set-cookie","name=123");//通过设置响应头来设置cookie		response.addHeader("set-cookie", "password=123456");		Cookie c = new Cookie("aihao" , "nv");//我们先new一个cookie对象		Cookie d = new Cookie("xingqu" , "nv");		response.addCookie(c);//将我们new 的cookie对象添加上去		response.addCookie(d);	}}

//服务器端获取cookiepublic class BServlet extends HttpServlet {	public void doGet(HttpServletRequest request, HttpServletResponse response)			throws ServletException, IOException {		response.setHeader("Content-Type", "text/html;charset=utf-8");		PrintWriter pw =response.getWriter();		Cookie[] cs = request.getCookies();		for(Cookie e : cs) {			pw.write(e.getName() + "=" + e.getValue() + "
"); } pw.close(); }}

cookie的其他方法

1 设置其最大存活时间 Cookie的maxAge

当服务器创建Cookie对象后,可以调用setMaxAge()方法设置Cookie的最大生命。

  maxAge > 0:表示Cookie在客户端硬盘上保存的最大时间,单位为秒;
  maxAge < 0:表示Cookie不会被浏览器保存到硬盘上,而只在浏览器内存中存活,一旦客户端关闭浏览器在,那么Cookie就消失;
  maxAge == 0:表示删除Cookie,例如客户端硬盘已经存在名为abc的Cookie,如果服务器再向客户端发送名为abc,并且maxAge为0的Cookie,那么表示删除客户端上的名为abc的Cookie。

2 设置其path路径

注意其path路径并不是你想的那样哦,当你设置了cookie的path路径后,当你访问的url路径包含在cookie的path路径中是,浏览器就会发送该cookie给服务器对象。

如果没有设置path路径,那么它的path默认为当前Servlet的所在路径。

我们了看看他的使用代码:

j's'p<%@page import="java.net.URLEncoder"%><%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%String path = request.getContextPath();String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";%>              My JSP 'jsp1.jsp' starting page    	

添加cookie

<% /* cookie不能保存中文所以使用中文是就必须得进行url编码 */ String name = URLEncoder.encode("魏金浩", "utf-8"); String value = URLEncoder.encode("呵呵哒", "utf-8"); Cookie c = new Cookie(name , value); c.setMaxAge(-1); c.setPath("/day_11/jsp/jsp1.jsp");/* 当我们这是了"/day_11/jsp1.jsp"path路径,我们在请求jsp2.jsp中浏览器就不会返回这个cookie了 */ response.addCookie(c); %>
<%@page import="java.net.URLDecoder"%><%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%String path = request.getContextPath();String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";%>              My JSP 'jsp2.jsp' starting page    	

得到COOKIE

<% String d = null; String e = null; Cookie[] c = request.getCookies(); if(c != null) { for(Cookie s : c) { String name = URLDecoder.decode(s.getName(),"utf-8");/* 进行解码 */ if("魏金浩".equals(name)) { d = name; String value = URLDecoder.decode(s.getValue(),"utf-8");/* 进行解码 */ e = value; } } } %> cookie: <%=d %>=<%=e %>
应为cookie是不允许传递中文的,这里面还涉及到了如何传递中文的方法,大家可以参考一下。

好了,cookie的内容咱们就说到这把,让我们在来研究一下session对象吧。

HttpSession

简介

HttpSession可和http协议无关了,这是我们的三大域对象之一(request,session,application),session域对象的域自然就是这个会话的过程了。我想这个不难理解吧。

也就是说服务器会为每个会话创建一个session对象,所以session中的数据可供当前会话中所有servlet共享。

常用方法

既然是域对象自然少不了这三个方法了:

session.setAttribute();session.getAttribute();session.removeAttribute();
这三个方法我们已近玩烂了,我就不细说了。

那摩我们如何得到session对象呢?

request.getSession();//得到session对象
好了,我们即能得到session了,也能设置属性了,他的大部分工作已经完成了,但是为了我们更好的使用session对象来实现数据的共享,我们有必要了解一下他的原理。

session原理

 1.session是依赖Cookie实现的。

  2.session是服务器端对象

  3.当用户第一次使用session时(表示第一次请求服务器),服务器会创建session,并创建一个Cookie,在Cookie中保存了session的id,发送给客户端。这样客户端就有了自己session的id了。但这个Cookie只在浏览器内存中存在,也就是说,在关闭浏览器窗口后,Cookie就会丢失,也就丢失了sessionId。

  4.当用户第二次访问服务器时,会在请求中把保存了sessionId的Cookie发送给服务器,服务器通过sessionId查找session对象,然后给使用。也就是说,只要浏览器容器不关闭,无论访问服务器多少次,使用的都是同一个session对象。这样也就可以让多个请求共享同一个session了。

  5.当用户关闭了浏览器窗口后,再打开浏览器访问服务器,这时请求中没有了sessionId,那么服务器会创建一个session,再把sessionId通过Cookie保存到浏览器中,也是一个新的会话开始了。原来的session会因为长时间无法访问而失效。

  6.当用户打开某个服务器页面长时间没动作时,这样session会超时失效,当用户再有活动时,服务器通过用户提供的sessionId已经找不到session对象了,那么服务器还是会创建一个新的session对象,再把新的sessionId保存到客户端。这也是一个新的会话开始了。
哦了,再多我也就不说了,要不然你们就嫌我啰嗦了,让我们来看一个应用吧!

演示登录功能:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%String path = request.getContextPath();String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";%>              My JSP 'log.jsp' starting page    	
method="post">

登陆

用户名:
密码:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%String path = request.getContextPath();String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";%>              My JSP 'success.jsp' starting page    	
<% HttpSession s = request.getSession(); String username = (String)s.getAttribute("username"); if(username == null) { response.sendRedirect(response.encodeURL("/day_11/LogServlet")); } %> hello <%=username %>
package sessiontest;import java.io.IOException;import java.io.PrintWriter;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 LogServlet extends HttpServlet {		public void doGet(HttpServletRequest request, HttpServletResponse response)			throws ServletException, IOException {		doPost(request, response);			}	public void doPost(HttpServletRequest request, HttpServletResponse response)			throws ServletException, IOException {		request.setCharacterEncoding("UTF-8");		String username = request.getParameter("username");		String password = request.getParameter("password");		if("weijinhao".equals(username)) {			if("123456".equals(password)) {				HttpSession s = request.getSession();				s.setAttribute("username",username);				response.setStatus(302);				response.setHeader("location", response.encodeURL("/day_11/session/success.jsp"));			}			else {				response.setStatus(302);				response.setHeader("location", response.encodeURL("/day_11/session/log.jsp"));			}		}		else {			response.setStatus(302);			response.setHeader("location", response.encodeURL("/day_11/session/log.jsp"));		}	}}
乍一看代码挺多但其实大部分都是不用看的,就看最主要的就行了,你懂的。

我估计大家会问我为什么提交表单和重定向是使用response.encodeURL();呢我们来讲解一下:

URL重写

 session依赖Cookie,这是因为服务器需要把sessionId保存到客户端。如果用户的浏览器关闭了Cookie功能,那么session不能使用了!
 还可以在浏览器关闭了Cookie后使用URL重写的方法保存sessionId,这需要在每个URL后面都加上sessionId!这样用户的请求中就包含了sessionId,服务器就可以通过sessionId找到对应的session对象了。
  使用response.encodeURL()方法对URL进行编码,这样URL中会智能的添加sessionId。
 当浏览器支持cookie时,response.encodeURL()方法不会在URL后追加sessionId
  当浏览器不支持cookie时,response.encodeURL()方法会在URL后追加sessionId

session的API:

 String getId():获取sessionId;

 nt getMaxInactiveInterval():获取session可以的最大不活动时间(秒),默认为30分钟。当session在30分钟内没有使用,那么Tomcat会在session池中移除这个session;

 void setMaxInactiveInterval(int interval):设置session允许的最大不活动时间(秒),如果设置为1秒,那么只要session在1秒内不被使用,那么session就会被移除;

long getCreationTime():返回session的创建时间,返回值为当前时间的毫秒值;

long getLastAccessedTime():返回session的最后活动时间,返回值为当前时间的毫秒值;

void invalidate():让session失效!调用这个方法会被session失效,当session失效后,客户端再次请求,服务器会给客户端创建一个新的session,并在响应中给客户端新session的sessionId;

 boolean isNew():查看session是否为新。当客户端第一次请求时,服务器为客户端创建session,但这时服务器还没有响应客户端,也就是还没有把sessionId响应给客户端时,这时session的状态为新。

最后还得说一下:

session与浏览器

 session对象是保存在服务器端的,而sessionId是通过Cookie保存在客户端的。
 因为Cookie不能在多个浏览器中共享,所以session也不能在多个浏览器中共享。也就是说,使用IE登录后,再使用FireFox访问服务器还是没有登录的状态。
 而且同时打开多个相同浏览器的窗口,是在使用同一session。如果你使用的是老浏览器,例如IE6,那么就会每个窗口一个session。

哦了,我们就聊到这里,我要去睡觉了。

你可能感兴趣的文章
Leetcode C++《热题 Hot 100-29》22.括号生成
查看>>
Leetcode C++《热题 Hot 100-40》64.最小路径和
查看>>
Leetcode C++《热题 Hot 100-41》75.颜色分类
查看>>
Leetcode C++《热题 Hot 100-42》78.子集
查看>>
Leetcode C++《热题 Hot 100-43》94.二叉树的中序遍历
查看>>
Leetcode C++ 《第175场周赛-1 》5332.检查整数及其两倍数是否存在
查看>>
Leetcode C++ 《第175场周赛-2 》5333.制造字母异位词的最小步骤数
查看>>
Leetcode C++ 《第175场周赛-3》1348. 推文计数
查看>>
Leetcode C++《热题 Hot 100-44》102.二叉树的层次遍历
查看>>
Leetcode C++《热题 Hot 100-45》338.比特位计数
查看>>
读书摘要系列之《kubernetes权威指南·第四版》第一章:kubernetes入门
查看>>
Leetcode C++《热题 Hot 100-46》739.每日温度
查看>>
Leetcode C++《热题 Hot 100-47》236.二叉树的最近公共祖先
查看>>
Leetcode C++《热题 Hot 100-48》406.根据身高重建队列
查看>>
《kubernetes权威指南·第四版》第二章:kubernetes安装配置指南
查看>>
Leetcode C++《热题 Hot 100-49》399.除法求值
查看>>
Leetcode C++《热题 Hot 100-51》152. 乘积最大子序列
查看>>
[Kick Start 2020] Round A 1.Allocation
查看>>
Leetcode C++ 《第181场周赛-1》 5364. 按既定顺序创建目标数组
查看>>
Leetcode C++ 《第181场周赛-2》 1390. 四因数
查看>>