SpringMVC系列五之cookie与session

  • cookie与session的原理
  • 介绍
  • 类比
  • 作用
  • 形式
  • 区别
  • 使用场景
  • 流程图
  • cookie与session的程序实现
  • 工程目录
  • 搭建基本框架
  • cookies
  • jsessionid cookies
  • 自定义cookie
  • 在服务端程序获取cookie
  • session
  • 前端页面使用session
  • 服务端使用session


cookie与session的原理

介绍

类比

cookie类比于银行卡,session类比于银行系统中保存的个人信息,会话类比于去银行办业务。只有拿着cookie,银行工作人员根据cookie从银行系统拿到你的sessIon并做相关操作,业务才能完成。

作用

cookie与session的作用是用于在同一网站下,不同网页的跳转过程中,协同维护一个上下文。这个上下文通常叫做会话,cookie与session存放了一些全局性信息或者全局性变量。

形式

cookie是以文本的形式存在,它存放在客户端(每个浏览器都有自己的存放路径)
session是以内存块的形式存在,它在服务器内存中

区别

cookie适用于存放少量的基本信息,session适用于存放大量信息。
session比Cookie更具有安全性
session占用服务器性能,Session过多,增加服务器压力
单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie

使用场景

购物网站从登陆,选购商品,加入购物车,进行结算这个过程中,有多次网页的跳转,使用cookie和session来保存全局信息,使得购物车能看到加入的商品,结算能看到购物车要结算的商品。

注意:cookie和session一般都是同时使用,共同维护会话

流程图

下图展现了一个会话过程,黄色方框代表浏览器和服务器的会话,服务端为这个会话在内存中创建了一个session。服务段程序在每个与浏览器交互的过程中,都可以创建自定义cookie,也可以随时在session中存取数据。

spring 禁用cookie springsession cookie_spring 禁用cookie

cookie与session的程序实现

工程目录

搭建基本框架

  1. 创建动态网页工程(Dynamic web project)
  2. 将所需的jar包复制到lib目录下
  3. 编写web.xml
  4. 编写springmvc配置文件
  5. 编写index.jsp。
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>测试页</title>
</head>
<body>
	<a href="login">请登录</a>
	
	<h1>游客可浏览信息</h1>
	<h1>游客可浏览信息</h1>
	<h1>游客可浏览信息</h1>
	<h1>游客可浏览信息</h1>
	
</body>
</html>
  1. 编写视图界面
    在WEB-INF下创建view文件夹,在该文件夹下创建1个界面:login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>测试页</title>
</head>
<body>
	<form action="login" method="post">
		用户:<input type="text" name="username" /><br/>
		密码:<input type="text" name="password" /><br/>
		<input type="submit" value="登录">
	</form>
	
</body>
</html>
  1. 编写controller中的基本方法
package com.edu.tjdz.geng.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
public class MyController {
	
	//进入login.jsp
	@RequestMapping(value="/login", method = RequestMethod.GET )
	public String login() {
		return "login";
	}
	
	//处理登录按钮发出的请求,进入登录后的界面loginSuccess.jsp
	@RequestMapping(value="/login", method = RequestMethod.POST )
	public String login(String username, String password) {
		System.out.println("登录用户名为:" + username + ",密码为: " + password );
		return "loginSuccess";
	}
}
  1. 启动项目,测试基本框架是否有问题

cookies

jsessionid cookies

  1. 删除浏览器中全部cookie。(不同浏览器,删除方法不同,请自行百度,我使用的是谷歌浏览器)
  2. 在浏览器地址栏输入http://localhost:8080/SpringMVC07/(先不要敲回车,如果敲了重复步骤1和2),之后按F12,开启调试模式。
  3. 开启下面的界面后,再在地址栏敲回车。
  4. 捕捉请求信息:在SpringMVC07/这个请求中,找到ResponseHeaders,找到Set-Cookie,这个就是服务端发给浏览器的cookie要包含的信息。这个cookie的内容是JSESSIONID,它就是流程图中绿色session的id。(结合流程图理解)
  5. 点击请登录超链接
    可以发现Request中的cookie中的内容依然是上面的JESSIONID值,没有变化

spring 禁用cookie springsession cookie_java_02


6. 使用任意数据登录,继续查看cookie

依然没有变化,

spring 禁用cookie springsession cookie_spring 禁用cookie_03


7.总结: jsessionid这个cookie自生成后,此后不论发生多少次网页跳转,只有浏览器不关闭,它的值一直不变。这个cookie产生于浏览器第一次访问该网站。在后续访问网站的其他网址时,浏览器每次发出请求都会携带上cookie,方便后台程序使用。

自定义cookie

cookie的本质就是一个名值对,它也可以由程序员自定义,可以在任意需要的时刻定义。
以登录为例,我在登录的时候创建两个cookie,分别存放用户名和密码

  1. 修改controller的login函数
package com.edu.tjdz.geng.controller;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
public class MyController {
	
	@RequestMapping(value="/login", method = RequestMethod.GET )
	public String login() {
		return "login";
	}
	
	//新生成cookie需要使用HttpServletResponse对象
	@RequestMapping(value="/login", method = RequestMethod.POST )
	public String login(String username, String password, HttpServletResponse response) {
		System.out.println("登录用户名为:" + username + ",密码为: " + password );
		//创建cookie信息,在构造函数中设置名字和值,第一个参数是名字,第二个参数是值。
		Cookie userCookie = new Cookie("username", username);
		Cookie pwdCookie = new Cookie("password", password);
		//将cookie信息放到回应response中
		response.addCookie(userCookie);
		response.addCookie(pwdCookie);
		return "loginSuccess";
	}
}
  1. 在浏览器中输入如下网址,进入下面的网页中,并按F12
  2. 输入用户名和密码,点击登录,并捕捉请求和回应
    登录按钮的请求触发了login(String username, String password, HttpServletResponse response) 这个函数执行,函数执行生成两个cookie信息,并将他们放到回应response中,浏览器收到回应就会在本地创建这两个cookie。
  3. 在登录成功界面任意写一个链接
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>登录成功</title>
</head>
<body>
	
	<h1>欢迎登录</h1>
	
	<a href="/student"></a>
</body>
</html>

在controller中写一个处理/student请求的方法get

package com.edu.tjdz.geng.controller;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
public class MyController {

	@RequestMapping(value="/student", method = RequestMethod.GET)
	public String get() {
		return "getSuccess";
	}
	
	@RequestMapping(value="/login", method = RequestMethod.GET )
	public String login() {
		return "login";
	}
	
	@RequestMapping(value="/login", method = RequestMethod.POST )
	public String login(String username, String password, HttpServletResponse response) {
		System.out.println("登录用户名为:" + username + ",密码为: " + password );
		Cookie userCookie = new Cookie("username", username);
		Cookie pwdCookie = new Cookie("password", password);
		response.addCookie(userCookie);
		response.addCookie(pwdCookie);
		return "loginSuccess";
	}
}

编写getSuccess.jsp页面

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>个人中心</title>
</head>
<body>
	<h>进入个人中心</h>
</body>
</html>
  1. 刷新页面,点击个人中心,捕捉请求和回应
    就可以发现新的cookie已经随着浏览器请求一起发送到了服务端

在服务端程序获取cookie

cookie 可以在服务端controller任意程序中获取,在SpringMVC中使用注解@CookieValue获取
注解中name为cookie的名字,required设置为false。这就可以在任意地方使用cookie中存放的信息了(把它看做一个全局变量)

  1. 修改controller中的get函数
@RequestMapping(value="/student", method = RequestMethod.GET)
	public String get(@CookieValue(name = "JSESSIONID", required = false)String jid, @CookieValue(name = "username", required = false)String username, 
			@CookieValue(name = "password", required = false)String password) {
		System.out.println("session id 是:" + jid);
		System.out.println("当前登录用户名为:" + username + ",密码为: " + password );
		return "getSuccess";
	}
  1. 测试,点击个人中心,观察后台输出

    输出

session

前端页面使用session

由于cookie的数量有限制,安全性也较低,为了满足更多需求,可以使用session。session是在第一次访问网站时创建出来的,我们使用时不需要再创建。Springmvc中可以使用注解@SessionAttributes使用session

  1. 在controller头部增加了注解SessionAttributes,修改get方法,增加update方法
package com.edu.tjdz.geng.controller;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.servlet.ModelAndView;

@SessionAttributes(value = {"message1","message2"})
@Controller
public class MyController {
	
	@RequestMapping(value="/login", method = RequestMethod.GET )
	public String login() {
		return "login";
	}
	
	@RequestMapping(value="/login", method = RequestMethod.POST )
	public String login(String username, String password, HttpServletResponse response) {
		System.out.println("登录用户名为:" + username + ",密码为: " + password );
		Cookie userCookie = new Cookie("username", username);
		Cookie pwdCookie = new Cookie("password", password);
		response.addCookie(userCookie);
		response.addCookie(pwdCookie);
		return "loginSuccess";
	}
	
	//get方法中使用modelAndView在session中存放信息
	@RequestMapping(value="/student", method = RequestMethod.GET)
	public ModelAndView get(@CookieValue(name = "JSESSIONID", required = false)String jid, @CookieValue(name = "username", required = false)String username, 
			@CookieValue(name = "password", required = false)String password) {
		System.out.println("session id 是:" + jid);
		System.out.println("当前登录用户名为:" + username + ",密码为: " + password );
		
		ModelAndView modelAndView = new ModelAndView();
		//modelAndView中的键值对也可以放在session中
		//放置方法是把modelAndView中的键添加到Controller头部中注解@SessionAttributes中
	    //@SessionAttributes(value = {"message1","message2"})
		modelAndView.addObject("message1", "ABCDEF");
		modelAndView.addObject("message2", 123456);
		modelAndView.setViewName("getSuccess");
		return modelAndView;
	}
	
	@RequestMapping(value="/student", method = RequestMethod.PUT)
	public String update() {
		System.out.println("更新个人信息");
		return "updateSuccess";
	}
}
  1. 在页面中获取session中存放的信息
    修改getSuccess.jsp,增加了一个修改个人信息的按钮
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>个人中心</title>
</head>
<body>
	<h>进入个人中心</h>
	<br/>
	<br/>
	<form action="student" method="post">
		<input type="hidden" name="_method" value="put">
		<input type="submit" value="修改个人信息">
	</form>
</body>
</html>

增加修改个人信息的页面

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" isErrorPage="true"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>更新个人信息</title>
</head>
<body>
	<h>更新页面</h>	
	<h1>${message1} </h1>
	<h1>${message2} </h1>
</body>
</html>

重新登录,点击个人中心,进入下面页面

spring 禁用cookie springsession cookie_spring 禁用cookie_04


点击修改个人信息,可以在页面上显示session中存放的信息

spring 禁用cookie springsession cookie_spring 禁用cookie_05

服务端使用session

  1. 修改controller的update方法
    后台程序使用session,需要在函数参数列表中增加HttpSession session。
    在函数内,通过session.getAttribute(键名)来获得对应的信息。
@RequestMapping(value="/student", method = RequestMethod.PUT)
	public String update(HttpSession session) {
		System.out.println("更新个人信息");
		String message1 = (String) session.getAttribute("message1");
		int message2 = (int) session.getAttribute("message2");
		System.out.println("messaget1 是:" + message1 + " messaget2 是:" + message2 );
		
		return "updateSuccess";
	}
  1. 重新登录,点击个人中心,进入下面页面, 点击修改个人信息,观察eclipse后台输出

spring 禁用cookie springsession cookie_spring_06

  1. 结果如下:

spring 禁用cookie springsession cookie_spring 禁用cookie_07