会话技术知识点整理(Cookie和Session)
Posted 大忽悠爱忽悠
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了会话技术知识点整理(Cookie和Session)相关的知识,希望对你有一定的参考价值。
会话: 一次会话中包含多次请求和响应
一次会话: 浏览器第一次给服务器资源发送请求,会话建立,直到有一方断开为止
功能
在一次会话的范围内的多次请求间共享数据
方式
- 客户端会话技术: cookie
2.服务器端会话技术; session
Cookie
概念: 客户端会话技术,将数据保存到客户端
基础使用步骤
修改servlet模板代码,方便编程
第一步:
第二步:
第三步:
第四步:
代码演示
CookieServlet1: ---->发送Cookie方
@WebServlet("/CookieServlet1")
public class CookieServlet1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.创建Cookie对象
Cookie c=new Cookie("msg","hello");
//2.发送Cookie
response.addCookie(c);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
CookieServlet1:接收Cookie方
@WebServlet("/CookieServlet")
public class CookieServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取Cookie
Cookie[] cs = request.getCookies();
if(cs!=null)
{
for(Cookie c:cs)
{
String name = c.getName();
String value = c.getValue();
System.out.println(name+" "+value);
}
}
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
Cookie实现原理
基于响应头set_cookie和请求头cookie实现
第一次访问服务器,响应头会返回 set-Cookie:
第二次访问,会带着上次请求返回的 Cookie 访问:
也需要注意,第一次 访问 Cookie1,接收到返回的 set-Cookie,第二次不是只有访问 cookie2 ,才能在响应头里看到Cookie,第二次访问哪个都会被携带,这里只是,我们在 Cookie2 这个页面设置了接收 Cookie 的数组,会被打印出来而已。
Cookie细节
一次发送多个Cookie
创建多个Cookie对象,使用response调用多次addcookie方法发送cookie即可
//1.创建Cookie对象
Cookie c=new Cookie("msg","hello");
Cookie c1=new Cookie("msg","hello");
//2.发送Cookie
response.addCookie(c);
response.addCookie(c1);
Cookie在浏览器中保存的时间
默认情况下,浏览器被关闭后,cookie数据被销毁
Cookie的持久化存储
setMaxAge(int seconds)--->秒
- 正数: 将Cookie数据写到硬盘文件中,持久化存储. Cookie存活时间
- 负数:默认值
- 0:删除Cookie信息
Cookie能不能存储中文数据
- tomcat 8版本之前,Cookie中不能直接存储中文数据
需要将中文数据转码,一般采用URL编码(%E3) - tomcat 8版本之后,Cookie中支持中文数据
特殊字符还是不支持,建议使用URL编码存储,URL编码解析,例如空格
Cookie共享问题
1 假设在一个tomcat服务器中,部署了多个web项目,那么这些web项目中cookien能不能共享?
- 默认情况下cookie不能共享
setPath(String path): 设置Cookie的共享范围. 默认情况下,设置为当前的虚拟目录
如果要共享,可以将Cookie设置为"/"
/----->当前项目的根路径—>localhost/
注意: 以上方法是用来解决同一个服务器下,多个web项目的Cookie共享问题
2 不同tomcat服务器间Cookie共享问题 ?
setDomain(String path):如果设置一级域名相同,那么多个服务器之间Cookie可以共享
例如:
setDomain(".baidu.com"),那么tieba.baidu.com和news.baidu.com中的Cookie可以共享
Cookie的特点和作用
特点:
- Cookie存储数据在客户端浏览器
- 浏览器对于单个Cookie的大小由限制(4kb),以及对同一域名下的总Cookie数量也有限制(20)
作用:
- Cookie一般用于存储少量的不太敏感的数据
- 在不登录的情况下,完成服务器对客户端的身份识别
案例: 记住上一次访问时间
注意: cookie不支持特殊字符,因此需要采用URL编码存储,用URL解码来解析
代码加注释:
package com.example.Cookie1;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
@WebServlet("/CookieServlet")
public class CookieServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置响应消息体的数据格式以及编码
response.setContentType("text/html;charset=utf-8");
//判断是否有cookie的值为lastTime
boolean flag=false;
//获取所有Cookie
Cookie[] cookies = request.getCookies();
//遍历Cookie数组
if(cookies!=null&&cookies.length>0)
{
for(Cookie c:cookies)
{
//获取cookie的名称
String name = c.getName();
//判断名称是否是lastTime
if("lastTime".equals(name))
{
//有该cookie,说明不是第一次访问
flag=true;//有lastTime的cookie
//响应数据
//获取cookie的value---->时间
String value = c.getValue();
System.out.println("解码前:"+value);
//URL: 解码
value= URLDecoder.decode(value, "utf-8");
System.out.println("解码后:"+value);
response.getWriter().write("<h1>欢迎回来,您上一次访问的时间为:"+value+"</h1>");
//设置Cookie的value
//获取当前时间的字符串,重新设置cookie的值,重新发送cookie
Date date = new Date();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年mm月dd日 HH:mm:ss");
String format = simpleDateFormat.format(date);
//URL编码
System.out.println("编码前: "+format);
format=URLEncoder.encode(format,"utf-8");//
System.out.println("编码后:"+format);
//设置cookie的值
c.setValue(format);
//设置cookie的存活时间---一个月
c.setMaxAge(60*60*24*30);
//发送cookie
response.addCookie(c);
break;
}
}
}
if(cookies==null||cookies.length==0||flag==false)
{
//没有,说明是第一次访问
//设置Cookie的value
//获取当前时间的字符串,重新设置cookie的值,重新发送cookie
Date date = new Date();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年mm月dd日 HH:mm:ss");
String format = simpleDateFormat.format(date);
Cookie c=new Cookie("lastTime",format);
//URL编码
System.out.println("编码前: "+format);
format=URLEncoder.encode(format,"utf-8");//
System.out.println("编码后:"+format);
//设置cookie的值
c.setValue(format);
//设置cookie的存活时间---一个月
c.setMaxAge(60*60*24*30);
//发送cookie
response.addCookie(c);
response.getWriter().write("<h1>欢迎首次访问</h1>");
}
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
Session
概念
服务器端会话技术,在一次会话的多次请求间共享数据,将数据保存在服务器端的对象中。 HttpSession
一次会话的概念
一次会话,什么是一次会话呢?我举个例子:就我们现在上网,打开浏览器浏览网站当时开始到你关闭浏览器,就称之为一次会话;
HttpSession对象—共享数据
1 获取HttpSession对象
request.getsession()
2 使用HttpSession对象
Object getAttribute(String name)
void setAttribute(String name,Object value)
void removeAttribute(String name)
代码演示:
Demo1Servlet :
@WebServlet("/SessionDemo1")
public class SessionDemo1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//使用session共享数据
//1.获取session数据
HttpSession session = request.getSession();
//2.存储数据
session.setAttribute("msg","大忽悠");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
Demo2Servlet:
@WebServlet("/SessionDemo2")
public class SessionDemo2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.获取session
HttpSession session = request.getSession();
//2.获取数据
Object msg = session.getAttribute("msg");
System.out.println(msg);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
Session原理
Session的实现是依赖与Cookie的
当客户端关闭后,服务器不关闭,两次获取session是否为同一个
默认情况下不是,因为客户端关闭后,一次会话就结束了.
如果需要相同,则可以创建Cookie,键为JSESSIONID,让Cookie持久化保存
代码演示:
//1.获取session
HttpSession session = request.getSession();
Cookie c=new Cookie("JSESSIONID",session.getId());
c.setMaxAge(60*60);
response.addCookie(c);
//2.获取数据
Object msg = session.getAttribute("msg");
System.out.println(msg);
客户端不关闭后,服务器关闭,两次获取session是否为同一个
不是同一个,但是要确保数据不丢失
1.session钝化: 在服务器正常关闭之前,将session对象系列化到硬盘上
2.session活化: 在服务器启动后,将session文件转化为内存中的session对象即可
tomcat服务器会自动完成钝化和活化过程,但是IDEA不会,因此一般将项目直接放到tmocat的webapps目录下
Session被销毁时机
服务器关闭时,session对象被销毁
session对象调用invalidate()来销毁自己
session默认失效时间为30分钟
我们可以对默认失效时间进行修改:
web.xml配置文件目录,大概500-600多行:
session特点
- session用于存储一次会话的多次请求的数据,存储在服务器端
- session可以存储任意类型,任意大小的数据
session与cookie的区别
- session存储数据在服务器端,cookie在客户端
- session没有数据大小限制,而cookie有
- session数据安全,cookie相对于不安全
验证码案例
1.案例需求
2.案例分析
在访问浏览器时,会有两个请求,因为验证码图片试一次单独的请求
完整代码
需要导入的jar包:
配置文件:
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql:///test1
username=root
password=xxxx
#初始化连接数量
initialSize=5
#最大连接数
maxActive=10
#最大等待时间
maxWait=3000
login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>战地六游戏官网</title>
<script>
window.onload=function(){
document.getElementById("img").onclick=function (){
this.src="/ZhanDi/CheckCodeServlet?time="+new Date().getTime();
}
}
</script>
<style>
div{
color: red;
}
</style>
</head>
<body>
<form action="/ZhanDi/LoginServlet" method="get">
<table>
<tr>
<th>用户名:</th>
<td><input type="text" placeholder="请输入用户名" name="username"></td>
</tr>
<tr>
<th>密码:</th>
<td><input type="password" placeholder="请输入密码" name="password"></td>
</tr>
<tr>
<th>验证码:</th>
<td><input type="text" placeholder="请输入验证码" name="checkcode"></td>
</tr>
<tr>
<td colspan="2"> <img id="img" src="/ZhanDi/CheckCodeServlet"></td>
</tr>
<tr>
<td colspan="2"> <input type="submit" value="登录"></td>
</tr>
</table>
</form>
<div><以上是关于会话技术知识点整理(Cookie和Session)的主要内容,如果未能解决你的问题,请参考以下文章