会话技术(Session、Cookie)详细介绍
会话技术
request:接收请求
接收请求行
- 接收请求方式:request.getMethod()
- 接收项目路径:request.getContextPath()
接收请求头
- request.getHeader(String name)
接收请求参数
中文参数:
- get方式:不乱码。因为tomcat8.5已经帮我们解决了
- post方式:乱码: request.setCharacterEncoding(“utf-8”)
- 接收单值的:String value = request.getParameter(String name)
- 接收多值的:String[] values = request.getParameterValues(String name)
- 接收所有: Map
map = request.getParameterMap()
其它作用:
是一个域对象
- 何时创建:一次请求开始
- 何时销毁:一次请求结束
- 作用范围:一次请求期间
可以实现请求转发
- request.getRequestDispatcher(“/login.jsp”).forward(req,resp)
response:用于设置响应的
设置响应行
- 设置响应状态码:response.setStatus(int code)
设置响应头
- response.setHeader(String name,String value)
设置响应体
- 字节流方式 :response.getOutputStream()
字符流方式:
- 处理中文响应乱码:response.setContentType(“text/html;charset=utf-8”)
- response.getWriter().print(String string)
- 重定向跳转:response.sendRedirect(“/test/index.jsp”)
请求转发和重定向的区别:
- 重定向 2次请求; 请求转发 1次请求
- 重定向 地址栏会变; 请求转发 地址栏不变
- 重定向 是浏览器跳转; 请求转发 是服务器跳转
- 重定向 可以跳转任意地址; 请求转发只能跳转项目内的资源
什么时候用请求转发?什么时候用重定向?
- 如果跳转时有数据要传递,要使用请求转发;
- 否则可以使用重定向
一、会话技术介绍
目标
- 了解什么是会话
- 了解什么是会话技术
- 理解会话技术的特点【重点】
讲解
1. 什么是会话
“会话”是引用了现实生活中的概念。
现在生活中的“会话”,比如:电话通话。双方建立连接之后,可以有多次应答,最后断开结束会话
我们所说的“会话”,双方指的是客户端和服务端
- 会话开始:客户端和服务端建立连接
- 会话过程:可以有多次请求和响应
- 会话结束:关闭浏览器,会话结束
2. 什么是会话技术
会话技术:用于存储会话过程中的一些数据的技术,用于在同一会话内部共享数据的技术
会话技术的特点:
- 会话技术是存储数据的技术
- 会话技术存储的数据:在一个会话内多次请求之间,数据要共享
- 会话技术存储的数据:在不同会话之间,数据应该相互独立、互不干扰的
简单来说:
- 我访问京东,我跟京东的会话,添加的购物车数据,是我的
- 你访问京东,你跟京东的会话,添加的购物车数据,是你的
- 两个人的数据,应该互不干扰
3. 有哪些会话技术
Cookie:客户端的会话技术,会话数据存储在客户端浏览器
- 不安全;只能存储字符串
- 服务器压力小
session:服务端的会话技术,会话数据存储在服务端。
- 更安全;可以存储任意类型的对象
- 服务器压力大
二、Cookie
1. Cookie的使用流程【重点】
目标
- 了解Cookie技术的使用过程
- 使用Cookie的主要API,完成Cookie的创建、发送、接收
讲解
Cookie的使用过程
Cookie的使用示例
创建Cookie,返回给客户端
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;@WebServlet(urlPatterns=”/createCookie”)
public class Demo01CreateCookieServlet extends HttpServlet {@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1. 创建一个Cookie: name和value都不支持中文、空格、特殊符号,建议只使用字母、数字
Cookie cookie = new Cookie("name", "ErGe");
//2. 把Cookie添加到response里
// 最终会把Cookie放在响应头里,返回给客户端 Set-Cookie: name=ErGe
response.addCookie(cookie);
//问题:能创建多少个Cookie返回给客户端?可以创建任意个,但是浏览器只能接收有限数量的Cookie
// 按照Servlet规范:一个浏览器为每个服务器支持20个Cookie,一个浏览器总共支持300个Cookie;
// 每个Cookie限制4KB
Cookie cookie2 = new Cookie("sex", "male");
response.addCookie(cookie2);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
接收客户端携带的Cookie
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;@WebServlet(urlPatterns=”/getCookie”)
public class Demo02GetCookieServlet extends HttpServlet {@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1. 接收客户端携带到服务端的Cookie
// 浏览器会把Cookie自动放到请求头里,携带到服务端:Cookie: name=ErGe
Cookie[] cookies = request.getCookies();
for (Cookie cookie : cookies) {
System.out.println(cookie.getName() +": " + cookie.getValue());
}
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
演示操作的步骤
- 打开浏览器,先清除浏览器缓存:ctrl + shift + delete
再访问:
http://localhost:8080/demo/createCookie
- Servlet里创建了Cookie,把Cookie返回给了浏览器
- 浏览器会自动接收并保存Cookie数据
然后访问:
http://localhost:8080/demo/getCookie
- 浏览器发请求时,会自动把Cookie携带到服务端
- Servlet里的代码接收了Cookie,并把Cookie输出到了idea的控制台
- 最终实现了:一次会话内、多次请求之间的数据共享
2. 设置Cookie
Cookie的有效期
目标
- 了解Cookie的有效期
- 能说出Cookie的默认有效期
- 能设置Cookie的有效期
讲解
什么是Cookie的有效期
- 浏览器接收到Cookie之后,会存储多长时间。这个时间叫有效期
- Cookie数据并非永久存储的,那么可以存储到什么时候
Cookie默认有效期
- 一次会话期间(只要浏览器一关闭,Cookie就失效了)
演示操作的步骤:
- 打开浏览器,先清除缓存
访问http://localhost:8080/demo/createCookie:
- 服务端会创建Cookie,返回给客户端;
- 浏览器接收并存储Cookie
再访问http://localhost:8080/demo/getCookie:Cookie还是有效的
- 浏览器发请求时,会自动把Cookie携带到服务端
- 服务端可以接收到 Cookie
关闭浏览器,再打开后访问 http://localhost:8080/demo/getCookie:Cookie已经失效了
- 浏览器发请求时,已经没有Cookie
- 服务端再接收并输出,会报空指针异常
设置Cookie的有效期
- 设置有效期之后,在到期之前Cookie始终有效,无论浏览器是否关闭重启;
强制清除浏览器的缓存:一定可以清除Cookie
cookie.setMaxAge(int 秒数)
代码示例
修改
Demo01CreateCookieServlet
的代码import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet(urlPatterns="/createCookie")
public class Demo01CreateCookieServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1. 创建一个Cookie: name和value都不支持中文、空格、特殊符号,建议只使用字母、数字
Cookie cookie = new Cookie("name", "ErGe");
// 设置cookie的有效期为60秒
cookie.setMaxAge(60);
response.addCookie(cookie);
//2. 这个cookie,没有设置有效期
Cookie cookie2 = new Cookie("sex", "male");
response.addCookie(cookie2);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
演示过程:
修改
Demo01CreateCookieServlet
:- 给名称为name的Cookie设置有效期为60秒
- 名称为sex的Cookie,不设置有效期,有效期仍然是默认的一次会话(浏览器关闭就失效)
- 重启Tomcat
在浏览器里输入地址:
http://localhost:8080/demo/setCookie
服务端创建了两个Cookie,都返回给了浏览器。这两个Cookie分别是:
- 第一个Cookie:名称是name,值是ErGe,有效期:60秒
- 第二个Cookie:名称是sex,值是male,有效期:默认的
- 浏览器接收到Cookie后,会自动保存cookie
在60秒内:两个Cookie都有效
浏览器访问 http://localhost:8080/demo/getCookie
- 浏览器会把两个Cookie都自动携带到服务端
- 服务端可以接到这两个Cookie
在60秒内:关闭重启浏览器,名称为name的Cookie仍有效;名称为sex的Cookie失效了
浏览器访问 http://localhost:8080/demo/getCookie
- 浏览器会把还有效的Cookie(名称为name的)自动携带到服务端
- 服务端只能接到这一个名称为name的Cookie
60秒之后:两个Cookie都失效了
浏览器访问 http://localhost:8080/demo/getCookie
- 服务端接收不到,循环所有Cookie并输出,会报错
小结
- Cookie默认有效期:一次会话结束
设置Cookie有效期:cookie.setMaxAge(秒)
- 在cookie过期之前,无论是否关闭重启浏览器,Cookie始终有效
- 在cookie到期之后,会自动失效
- 注意:无论什么样的Cookie,只要清除浏览器缓存,都可以清除掉
3. 接收Cookie
目标
- 能够获取客户端携带的Cookie数据
讲解
API部分
- 接收Cookie:
Cookie[] cookies = request.getCookies()
。如果接收不到,返回值是null 从Cookie里获取数据:每个Cookie可以理解为是一个键值对数据(还有其它附加数据)
cookie.getName()
:获取Cookie的名称cookie.getValue()
:获取Cookie的值
封装一个工具类
用于获取指定名称的那个Cookie的值
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
public class CookieUtils {
public static String getCookieValue(HttpServletRequest request, String name){
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (Cookie cookie : cookies) {
if (name.equals(cookie.getName())) {
return cookie.getValue();
}
}
}
return null;
}
}
使用工具类,获取某个名称的Cookie值
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 接收Cookie,封装一个工具类
*/
@WebServlet(urlPatterns="/getcookie2")
public class Demo05GetCookieServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//要求:客户端发请求会把Cookie携带过来,但是我们只要获取其中名称为name的Cookie值
//要求:客户端发请求会把Cookie携带过来,但是我们只要获取其中名称为sex的Cookie值
String name = "name";
String value = CookieUtils.getCookieValue(request, name);
/*Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (Cookie cookie : cookies) {
if (name.equals(cookie.getName())) {
value = cookie.getValue();
break;
}
}
}*/
System.out.println("得到Cookie值是:" + value);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
三、session
1. session的使用过程
目标
- 了解session的使用过程
讲解
使用流程
使用示例
在任何Servlet里,如果要使用session对象,只需要两步:
得到一个session对象 :
HttpSession session = request.getSession()
- 如果当前会话有session对象,就直接返回这个对象
- 如果当前会话没有session对象,就会创建一个session对象
- 使用session存取数据:域对象的方法
代码演示的步骤:
- 打开浏览器,先清除缓存
访问 http://localhost:8080/demo/session1
服务端执行
request.getSession()
。- 当前会话还没有session对象,这个方法会创建一个session
- 然后tomcat会把session的id放到Cookie里,设置到response,最终会返回给浏览器
- 把名称为name的数据存储到session里
- 浏览器接收到Cookie:
JSESSIONID=session的id
再访问 http://localhost:8080/demo/session2
- 浏览器会自动把Cookie
JSESSIONID=session的id
携带到服务端 服务端执行
request.getSession()
- 当前会话已经有session对象,tomcat会接收Cookie中的JSESSIONID,找到当前会话的session
- 把找到的session返回给我们
- 我们可以从session里得到名称为name对应的数据
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;/**
- request.getSession():
- 如果本次请求所属的会话,已经有session对象了:直接得到这个session对象
- 如果本次请求所属的会话,还没有session对象: 方法会创建一个新的session对象
* - 问题:session里的数据,什么情况下会找不到?
- 如果session对象没有了,数据就找不到了
- 如果Cookie(JSESSIONID)没有了,数据也找不到了
* - 实际场景是:
- 如果在浏览器里打开新标签页,可以找到数据(客户端有JSESSIONID,服务端有session对象)
- 如果清除了浏览器缓存,再访问 找不到数据(客户端没有JSESSIONID了)
- 如果关闭重启了浏览器,再访问 找不到数据(客户端没有JSESSIONID了)
- 如果换一个浏览器访问, 找不到数据(客户端没有JSESSIONID)
- 如果服务端的session对象销毁了,找不到数据
- 如果服务器关闭重启了,session有没有销毁呢?
- 如果是正常关闭重启,session没有销毁
- 如果是非正常关闭重启,session会销毁掉
* 但是idea修改了tomcat的配置,每次重启都会强制销毁session对象
/
@WebServlet(urlPatterns=”/session1”)
public class Demo01SessionServlet extends HttpServlet {@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//1.得到一个session对象
HttpSession session = request.getSession();
System.out.println(“/session1里的id:” + session.getId());//2.把数据存储到session里
session.setAttribute(“name”, “tom”);//手动销毁session对象
session.invalidate();
session = request.getSession();
System.out.println(“/session1里销毁后重新获取的id:” + session.getId());
}@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request, response);
}
}
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;- 浏览器会自动把Cookie
@WebServlet(urlPatterns="/session2")
public class Demo02SessionServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1. 得到一个session对象
HttpSession session = request.getSession();
//2. 从session里取出数据
Object name = session.getAttribute("name");
System.out.println("session2里取数据:" + name);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
2. 获取session对象
目标
- 能够得到一个session对象
- 能够判断什么情况是创建新session、什么情况会获取旧session
讲解
- 获取session对象:
request.getSession()
什么时候会创建新的session?
- 客户端没有JSESSIONID
- 客户端有JSESSIONID,但是服务端没有对应的session对象了
什么时候会获取旧的session?
- 客户端有JSESSIONID,并且服务端有对应的session对象
什么时候session里的数据会找不到?
- 只要找不到旧的session对象,就找不到里边的数据了
- 浏览器关闭了,重启了,清除缓存了,换了浏览器
- 服务器非正常关闭了
还没有评论,来说两句吧...