技术之路-session和cookie的区别

session和cookie的区别


cookie存在于客户端(浏览器),session存在于服务端。session的主要信息存在于服务器,在客户端只存放一个sessionid(基于cookie的),每次请求,客户端都会自动把sessionid发送到服务端去(因为是通过cookie保存的sessionid,每次发送请求,客户端会自动发送cookie到服务端),服务端根据sessionid去session里获取信息,做相应的操作。

cookie--------------------------------------------

访问index.jsp页面
技术之路-session和cookie的区别_第1张图片
index.jsp页面源码

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>主页title>
head>
<body>
		<form action="/cookie-and-session/cookie" method="post">
			用户名:<input type="text" name="username" id="username" /><br />
			密码:<input type="text" name="password" id="password" /><br />
			<input type="submit" value="提交"/>
		form>
body>
html>

对应的CookieServlet服务端代码

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/cookie")
public class CookieServlet extends HttpServlet {

	/**
	* 无论是post还是get都会执行service方法
	*/
	@Override
	protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// 根据name获得用户名和密码
		String username = req.getParameter("username");
		String password = req.getParameter("password");
		// cookie里面只能保存String,不能保存汉字,非要保存用URLEncoder编码
		/*Cookie cookie1 = new Cookie("username", username);
		Cookie cookie2 = new Cookie("password", password);
		resp.addCookie(cookie1);
		resp.addCookie(cookie2);*/
		// 转发到success.jsp页面
		req.getRequestDispatcher("/success.jsp").forward(req, resp);
	}
}

打开开发者工具(博主是用的chrome)在Application->Storage->Cookies可以看到如下界面
有默认的sessionid
可是明明还没有使用session啊,怎么会有sessionid了呢。实际上,因为request是jsp的内置对象(实际上一个jsp页面,也就是一个servlet),所以在页面加载的时候,就会自动调用getSession()方法,获得一个session对象,并通过特殊的算法,生成一个sessionid发送到客户端,我们可以查看源码,在你当前工作空间下的.metadata文件夹下

E:\Projects\EclipseProject\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\work\Catalina\localhost\cookie-and-session\org\apache\jsp

技术之路-session和cookie的区别_第2张图片
接下来,取消掉CookieServlet里面的注释,重启服务器之后,在访问一次,输入用户名和密码,提交。
技术之路-session和cookie的区别_第3张图片
可以看到如下界面(已经把username和password存入了cookie里面)
技术之路-session和cookie的区别_第4张图片
cookie没有删除的方法,只有setMaxAge(int num)方法(单位:秒)
正数:代表多少秒
0:代表删除
负数:代表关闭浏览器才删除
当然这里为了方便是直接明文保存的,为了安全考虑,重要信息不要保存到cookie,或者加密存储。

session-------------------------------------------

还是index.jsp页面,只是提交的form的action路径换成了

/cookie-and-session/session

同样打开开发者工具,会发现cookie里面只有一个sessionid(如果有username和password是因为这个是上次的没删除,删除一下就好了,或者输入不同的用户名和密码,以示区分),博主这边即删除了username和password,也输入了不同的用户名和密码
为什么只有sessionid呢?
因为session是保存在服务端的,客户端只使用cookie保存一个sessionid,所以这里只能看到一个sessionid(当然跟第一次的sessionid不一样,因为重启服务器之后,session里面原来的数据也没有了,session和sessionid也就会重新生成)。

技术之路-session和cookie的区别_第5张图片
对应的SessionServlet的源码

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/session")
public class SessionServlet extends HttpServlet {
	@Override
	protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// 根据name获得用户名和密码
		String username = req.getParameter("username");
		String password = req.getParameter("password");
		// 由于保存在服务端,所有session里面可以保存任意类型的数据
		// 把username放到session里面去
		req.getSession().setAttribute("username", username);
		// 把password放到session里面去
		req.getSession().setAttribute("password", password);
		
		// 打印输入用户名和密码
		System.out.println("用户名:" + req.getSession().getAttribute("username"));
		System.out.println("密码:" + req.getSession().getAttribute("password"));
		
		req.getRequestDispatcher("/success.jsp").forward(req, resp);
	}
}

提交form表单之后,可以看到控制台已经打印了用户名和密码
技术之路-session和cookie的区别_第6张图片

控制台输出
这下确实可以说明session是保存在服务端的吧,不过由于信息保存在服务端,所以当用户多的时候,就会很占用系统资源,这个时候选择用cookie保存是一个很好的选择哦。

要是客户端禁用了cookie该怎么办呢?
这个时候就要用资源路径重写来解决这个问题了 resp.encodeURL(“路径”)
改写一下SessionServlet(博主测试是关闭了保存cookie的哈)

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/session")
public class SessionServlet extends HttpServlet {
	@Override
	protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		String username = req.getParameter("username");
		String password = req.getParameter("password");
		req.getSession().setAttribute("username", username);
		req.getSession().setAttribute("password", password);
		
		// 资源路径重写,解决客户端禁用cookie的问题
		String encodeURL = resp.encodeURL("/cookie-and-session/success");
		
		// 重定向
		resp.sendRedirect(encodeURL);
	}
}

然后在添加一个SuccessServlet

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/success")
public class SuccessServlet extends HttpServlet {
	@Override
	protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		
		// 在重写了资源路径之后,在打印输出用户名和密码
		System.out.println("用户名:" + req.getSession().getAttribute("username"));
		System.out.println("密码:" + req.getSession().getAttribute("password"));
		
		//跳转到success.jsp
		req.getRequestDispatcher("/success.jsp").forward(req, resp);
	}
}

输入用户名和密码提交表单之后可以看到路径已经改变了
资源路径重新之后
控制台也已经打印出信息了(这个是在SuccessServlet里面打印的哈)
控制台消息
好了,这篇博文到此结束,如有错误,欢迎各位小伙伴指正。

你可能感兴趣的:(Java)