JavaWeb——【Cookie&Session】——一篇文章走进会话Cookie&Session会话技术

Cookie&Session


1.概述

当用户通过浏览器访问web应用时,通常情况下,服务器需要对用户的状态进行跟踪。例如,用户在网站结算商品时,Web服务器必须根据请求用户的身份,找到该用户所购买的商品。在Web开发中,服务器跟踪用户信息的技术称为会话技术

2.会话技术

从打开一个浏览器访问某个站点,到关闭这个浏览器的整个过程,成为一次会话
会话技术分为Cookie和Session
Cookie:数据存储在客户端本地,减少服务器端的存储的压力,安全性不好,客户端可以清除cookie
Session:将数据存储到服务器端,安全性相对好,但是会增加服务器的压力

3.Cookie

Cookie技术是将用户的数据存储到客户端的技术,其存储格式是一个键和一个值构成的,随着服务器端的响应发送给客户端浏览器。然后客户端浏览器会把Cookie保存起来,当下一次再访问服务器时把Cookie再发送给服务器。
我们主要学习的是:

  • 1.服务器端怎样将一个Cookie发送到客户端
  • 2.服务器端怎样接受客户端携带的Cookie

3.1.Cookie API

为了封装 Cookie 信息,在 Servlet API 中提供了一个 Javax. servlet.http. Cookie类,该类包含生成 Cookie信息和提取 Cookie 信息各个属性的方法

3.1.1.构造方法

Cookie类只有一个构造方法
public Cookie(String name, String value)
参数name指定Cookie名称,value指定Cookie的值
注意:名称不能更改,值可以为任何值。

3.1.2.常见用方法

方法 描述
String getName() 获取Cookie名称
void setValue(String newValue)
String getValue() 设置/获取Cookie的值
void setMaxAge(int expiry)
int getMaxAge() 设置/获取Cookie存活时间,单位为秒
void setPath(String uri)
String getPath() 设置/获取该Cookie项的有效目录路径
void setDomain(String patten)
String getDomain() 设置/获取该Cookie的有效域
void setVersion(int v)
int setVersion() 设置 Cookie 采用的协议版本

3.2.Cookie规范

3.2.1.Cookie 大小

Cookie大小上限为4KB;

上面的数据只是HTTP的Cookie规范,但在浏览器大战的今天,一些浏览器为了打败对手,为了展现自己的能力,可能对Cookie规范“扩展”了一些,例如每个Cookie的大小为8KB,最多可保存500个Cookie等
注意,不同浏览器之间是不共享Cookie的。

3.2.2.Cookie与HTTP头

Cookie是通过HTTP请求和响应头在客户端和服务器端传递的

Cookie:请求头,客户端发送给服务器端
格式:
Cookie: a=A; b=B; c=C。即多个Cookie用分号离开;

Set-Cookie:响应头,服务器端发送给客户端;一个Cookie对象一个Set-Cookie:
格式:
Set-Cookie: a=A
Set-Cookie: b=B
Set-Cookie: c=C

3.2.3.Cookie的覆盖

如果服务器端发送重复的Cookie那么会覆盖原有的Cookie,
例如客户端的第一个请求服务器端发送的Cookie是:Set-Cookie: a=A;第二请求服务器端发送的是:Set-Cookie:a=AA,那么客户端只留下一个Cookie,即:a=AA。

4.使用

4.1.发送一个Cookie

1.创建Cookie:
Cookie cookie = new Cookie(String cookieName,String cookieValue);
示例:
Cookie cookie = new Cookie("username", "lisi");
浏览器收到的格式为:

注意:Cookie存储中文会乱码,需要专门对其编码和解码操作

2.设置Cookie在客户端的持久化时间:

cookie.setMaxAge(int seconds);
注意:如果不设置持久化时间,Cookie会存储在浏览器的内存中,浏览器关闭 Cookie信息销毁(会话级别的Cookie),如果设置持久化时间,Cookie信息会被持久化到浏览器的磁盘文件里
示例:
cookie.setMaxAge(10*60);
设置cookie信息在浏览器的磁盘文件中存储的时间是10分钟,过期后浏览器自动删除该cookie信息

3.设置Cookie的有效路径(携带路径)

cookie.setPath(String path);
注意:如果不设置携带路径,那么该cookie信息会在访问产生该cookie的web资源所在的路径都携带cookie信息
示例:
cookie.setPath("/Cookie");
表示访问Cookie应用中的任何资源都携带cookie

cookie.setPath("/Cookie/helloCookieServlet");
表示访问Cookie中的helloCookieServlet时才携带cookie信息

4.向客户端发送cookie:

response.addCookie(Cookie cookie);

5.删除客户端的cookie

如果想删除客户端的已经存储的cookie信息,那么就使用同名同路径的持久化时间为0的cookie进行覆盖即可

5.1.服务端接受Cookie

cookie信息是以请求头的方式发送到服务器端的:

1.通过request获得所有的Cookie
Cookie[] cookies = request.getCookies();

2.遍历Cookie数组,通过Cookie的名称获得我们想要的Cookie
for (Cookie cookie : cookies) { System.out.println(cookie.getValue()); }

3.案例-显示上次访问时间
第一次访问显示:第一次访问
之后每次访问显示对应的时间

public class LastAccessTimeServlet extends HttpServlet {
	protected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
		// 获得当前时间
		Date date = new Date();
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd-hh:mm:ss");
		String currentTime = format.format(date);

		// 1、创建Cookie 记录当前的最新的访问时间
		Cookie cookie = new Cookie("lastAccessTime", currentTime);
		cookie.setMaxAge(60 * 10 * 500);
		response.addCookie(cookie);

		// 2、获得客户端携带cookie ---- lastAccessTime
		String lastAccessTime = null;
		Cookie[] cookies = request.getCookies();
		if (cookies != null) {
			for (Cookie coo : cookies) {
				if ("lastAccessTime".equals(coo.getName())) {
					lastAccessTime = coo.getValue();
				}
			}
		}
		response.setContentType("text/html;charset=UTF-8");
		if (lastAccessTime == null) {
			response.getWriter().write("您是第一次访问");
		} else {
			response.getWriter().write("您上次的访问的时间是:" + lastAccessTime);
		}
	}
}

Session

1.概述

Cookie技术可以将用户的信息保存在各自的浏览器中,并且可以在多次请求下实现数据的共享。但是,如果传递的信息比较多,使用 Cookie技术显然会增大服务器端程序处理的难度,这时,可以使用 Session 实现, Session 是一种将会话数据保存到服务器端的技术。

为了区分不同用户的Session数据,客户端每次向服务器请求时都会带着一个SessionID的标记,通常情况下,SessionID是借助Cookie技术来传递值的。

2.Session API

Session是与每一个请求消息紧密相关的,为此,HttpServletRequest定义了用于获取Session对象的getSession()方法,有两个重载
public HttpSession getSession(boolean create);
public HttpSession getSession();
区别是根据传入的参数来判断是否创建新的HttpSession对象,如果为true,则在相关的HttpSession对象不存在时创建并返回新的HttpSession对象,否则不创建新的 HttpSession 对象

常用方法

方法 描述
String getId() 返回HttpSession id
long getCreationTime() 返回创建时间
long getLastAccessedTime() 返回最后一次发送与Session相关请求时间
void setMaxInactiveInterval(int interval); 设置当前HttpSession对象可空闲的以秒为单位的最长时间。
boolean isNew() 判断当前HttpSession对象是否新建的
void invalidate() 用于强制使Session对象无效
ServletContext getServletContext() 返回当前HttpSession对象所属的Web应用程序对象
void setAttribute(String name, Object value) 将一个对象与一个名称关联后存储到当前的HttpSession对象中
String getAttribute(String name) 返回指定名称的属性对象
void removeAttribute(String name) 删除指定名称的属性

3.使用

3.1.向Session中存入数据

  • 1.获得Session对象
    HttpSession session = request.getSession();
    此方法会获得专属于当前会话的Session对象,如果服务器端没有该会话的Session 对象会创建一个新的Session返回,如果已经有了属于该会话的 Session 直接将已有的 Session 返回(实质就是根据 JSESSIONID 判断该客户端是否在服务器上已经存在 session 了)
  • 2.向session中存取数据(session也是一个域对象)
    session.setAttribute(“username”, “wangwu”);
示例代码
/**
 * 往Session中存入数据
 * @author weidong
 */
public class AddSessionServlet extends HttpServlet {
	protected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
		
		//创建Session对象
		HttpSession session = request.getSession();
		//存入数据
		session.setAttribute("username", "wangwu");

		String id = session.getId();// 获取session对象的id
		
		// 手动创建一个存储JSESSIONID的Cookie 为该cookie设置持久化时间
		Cookie cookie = new Cookie("JSESSIONID", id);
		cookie.setPath("/Session/");
		cookie.setMaxAge(60 * 10);
		response.addCookie(cookie);
		
		//输出
		response.getWriter().write("JSESSIONID:" + id);
	}
}

3.2.读取Session中的数据

public class GetSessionServlet extends HttpServlet {

	protected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
		// 从session中获得存储的数据
		HttpSession session = request.getSession();
		Object attribute = session.getAttribute("username");
		response.getWriter().write(attribute + "");
	}
}

4.Session其它知识

1.Session对象的生命周期(面试题/笔试题)

创建:第一次执行request.getSession()时创建
销毁:

  • 1.服务器(非正常)关闭时
  • 2.session过期/失效(默认30分钟)
  • 3.手动销毁session
    session.invalidate();

2.时间的起算点,从何时开始计算30分钟?
从不操作服务器端的资源开始计时
也可以在工程的web.xml中进行配置

	<session-config>
		<session-timeout>30</session-timeout>
	</session-config>

3.Session作用范围
默认在一次会话中,也就是说在,一次会话中任何资源公用一个session对象
一次会话:用户打开浏览器,点击多个多个超链接,然后关闭浏览器,这个过程称为一次会话

5.案例,一次性验证码

使用 Session实现了用户登录的功能。但在实际开发中,为了保证用户信息的安全,都会在网站登录的界面中添加一次性验证码,从而限制人们使用软件来暴力猜测密码。一次性验证码的功能同样可以使用 Session来实现。

在ImgServlet(Response课程中有用过)中,将验证码的数据存入session中,后在LoginServlet中,将请求中提交过来的验证码与session中的进行对比,如果正确,则验证成功,并且将session中的验证码删除,因为需要保证session中的数据只能被用一次,防止重复提交数据,如果不正确,就使用request将错误信息显示,如果发现session中的数据为null,说明重复提交了数据。

代码结构

public class LoginServlet extends HttpServlet {
	@Override
	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("text/html;charset=utf-8");
		String re = request.getParameter("verifycode");
		String answer = (String) request.getSession().getAttribute("verifycode");
		PrintWriter out = response.getWriter();
		
		 if(answer == null){
			 out.printf("请不要重复提交");
            return;
        }
		
		if (re.equals(answer)) {
			request.getSession().removeAttribute("verifycode");
			out.printf("验证成功");
		} else {
			out.printf("验证失败");
		}
		out.flush();
		out.close();
	}
}

发布了230 篇原创文章 · 获赞 250 · 访问量 28万+

猜你喜欢

转载自blog.csdn.net/weixin_42247720/article/details/103889391