前言:本文章是Java Web后端技术系列的第五篇,主要介绍Tomcat服务器,接下来将持续更新,感兴趣的小伙伴欢迎持续关注。因为我也是刚接触Java web方面的知识,尚有许多不足,如有错误欢迎指正!
会话
B/S架构中:从浏览器第一次给服务器发送请求时,建立会话;直到有一方断开,会话结束。
一次会话包含多次请求响应。
HTTP协议是无状态协议,同一个会话中的连续多个请求是互相独立的,彼此互不了解。
会话技术就是存储浏览器和服务器之间的通信数据的。
客户端会话技术:cookie
服务器会话技术:session
Cookie
介绍
Cookie作用:在一次会话的多次请求之间共享数据,将数据保存到客户端(浏览器)
特点
- cookie存储数据都在客户端(浏览器)
- cookie的存储数据只能是字符串
- cookie单个大小不能超过4KB
- cookie存储的数据不太安全
- 只能保存字符串信息
相关API
- 设置数据到cookie中
创建cookie对象,设置数据 value
Cookie cookie = new Cookie(String name,String value);
通过response,响应(返回)cookie
response.addCookie(cookie);
- 从cookie中获取数据
通过request对象,接收cookie数组
Cookie[] cookies = request.getCookies();
遍历数组
Cookie原理
服务器端调用 addCookie
函数,会在响应头中加入 Set-Cookie
字段,将cookie的数据传给浏览器
浏览器拿到响应头后把信息存到本地cookie,发送请求的时候会把本地cookie也发给服务器
服务器通过 getCookies()
方法拿到浏览器传来的数据。
使用
基本使用
需求:写两个servlet类,一个在浏览器的cookie中添加数据,一个读取浏览器cookie的数据
package cookiedemo.start;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @Author: ChenJialian
* @Description: cookie入门案例
* @Date: Create in 22:51 2020/9/19
*/
public class startDemo extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Cookie c = new Cookie("name","jack");
resp.addCookie(c);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
package cookiedemo.start;
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;
/**
* @Author: ChenJialian
* @Description: cookie入门案例
* @Date: Create in 22:53 2020/9/19
*/
@WebServlet("/startDemo2")
public class startDemo2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Cookie[] cs = req.getCookies();
if(null!=cs){
for(Cookie c:cs){
System.out.println(c.getName());
System.out.println(c.getValue());
}
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
服务器发送多个Cookie
@WebServlet("/MultipleCookie")
public class MultipleCookie extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse
response) throws ServletException, IOException {
this.doPost(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse
response) throws ServletException, IOException {
// 1. 创建多个cookie对象
Cookie cookie1 = new Cookie("name","lucy");
Cookie cookie2 = new Cookie("age","18");
// 2. 通过response响应多个
response.addCookie(cookie1);
response.addCookie(cookie2);
}
}
Cookie在浏览器保存时间(重点)
- 默认情况下
浏览器关闭(会话结束),cookie销毁(内存) - 设置cookie的存活时间
cookie.setMaxAge(int second);
– 单位是秒
正数:指定存活时间,持久化浏览器的磁盘中,到期后自动销毁
负数:默认浏览器关闭,cookie销毁
零:立即销毁(自杀)
@WebServlet("/MaxAgeCookie")
public class MaxAgeCookie extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse
response) throws ServletException, IOException {
this.doPost(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse
response) throws ServletException, IOException {
// 1.创建cookie对象
Cookie cookie = new Cookie("product", "xiaomi10");
// 2.设置cookie存活时间
// cookie.setMaxAge(-1); // 默认值,浏览器关闭自动销毁
// cookie.setMaxAge(60);// 存活60秒,到期自动销毁
cookie.setMaxAge(0); // 立即销毁...
//3. response响应cookie
response.addCookie(cookie);
}
}
Cookie存储中文
- tomcat8之前的版本,不支持中文
- 使用URLEncoder编码、URLDecoder解码实现中文存储
- tomcat8以后的版本,支持中文
@WebServlet("/EncodeCookie")
public class EncodeCookie extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse
response) throws ServletException, IOException {
this.doPost(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse
response) throws ServletException, IOException {
String product = "中国话";
product= URLEncoder.encode(product, "UTF-8");
// 1.创建cookie对象
Cookie cookie = new Cookie("product", product);
// 2.response响应cookie
response.addCookie(cookie);
}
}
@WebServlet("/DecodeCookie")
public class DecodeCookie extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Cookie[] cs = req.getCookies();
if(null!=cs){
for(Cookie c:cs){
System.out.println(c.getName());
String value = c.getValue();
value = URLDecoder.decode(value,"UTF-8");
System.out.println(value);
}
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
Session
介绍
使用Cookie问题
- 最多存储4K字符串
- 存储数据不太安全
session作用:在一次会话的多次请求之间共享数据,将数据保存到服务器端
session工作流程如下
HttpSession域对象
方法
- 存储数据
void setAttribute(String name,Object value)
- 获取数据
Object getAttribute(String name)
- 删除数据
void removeAttribute(String name)
使用步骤 - 将数据存储到session中
1.通过rquest对象,获取session对象
HttpSession session = request.getSession();
2.操作session的API,存储数据
session.setAttribute("username","哈哈,呵呵");
- 从session中获取数据
1.通过rquest对象,获取session对象
HttpSession session = request.getSession();
2.操作session的API,获取数据
session.getAttribute("username");
生命周期
- 何时创建
用户第一次调用request.getSession()方法时创建,而不是创建会话时就创建 - 何时销毁
- 服务器非正常关闭。如果是正常关闭,会序列化后存储,而不是销毁
- 非活跃状态30分钟后:即浏览器完全不操作页面
- tomcat进行配置 /tocmat安装目录/conf/web.xml
- 也可以项目的web.xml文件中按照上面的格式设置
- tomcat进行配置 /tocmat安装目录/conf/web.xml
- 调用
session.invalidate();
自杀
- 作用范围
- 一次会话中,多次请求之间
- 注意:每一个浏览器跟服务器都是独立的会话
使用
基本使用
一个servlet将数据存入session,另一个取出并打印。
package com.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
/**
* @Author: ChenJialian
* @Description:
* @Date: Create in 23:45 2020/9/19
*/
public class SetSession extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession hs = req.getSession();
hs.setAttribute("username","Lee");
System.out.println("存入session");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
package com.servlet;
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;
/**
* @Author: ChenJialian
* @Description:
* @Date: Create in 23:45 2020/9/19
*/
@WebServlet("/GetSession")
public class GetSession extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession hs = req.getSession();
String str = (String)hs.getAttribute("username");
resp.getWriter().println(str);
resp.getWriter().write(str);
System.out.println("取出session"+str);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
Session原理
req.getSession()
的判断:
- 如果用户是第一次访问(没有携带JSESSIONID),则创建session对象,生成编号并返回
- 如果不是第一次访问,则查找JSESSIONID对应的session对象,如果找不到就创建。
验证:
SetSession中
GetSession中
三大域对象总结
经过上一篇文章和这篇文章的学习,我们了解了HTTPServletRequest
、ServletContext
和HttpSession
这三个域对象,下面对它们进行一些总结。
通用方法
设置数据
void setAttribute(String name, Object o)
获取数据
Object getAttribute(String name)
删除数据
void removeAttribute(String name)
生命周期
ServletContext域对象
- 何时创建
服务器正常启动,项目加载时,创建 - 何时销毁
服务器关闭或项目卸载时,销毁 - 作用范围
整个web项目(共享数据)
HttpSession域对象
- 何时创建
用户第一次调用request.getSession()方法时,创建 - 何时销毁
服务器非正常关闭
未活跃状态30分钟
自杀 - 作用范围
一次会话中,多次请求间(共享数据)
HttpServletRequest域对象
- 何时创建
用户发送请求时,创建 - 何时销毁
服务器做出响应后,销毁 - 作用范围
一次请求中,多次转发间(共享数据)
总结
- 使用原则:能用小的不用大的,最小的是
HttpServletRequest
- 常用的场景:
- request:一次查询的结果(servlet转发jsp)
- session:存放当前会话的私有数据
- 用户登录状态
- 验证码
- 购物车
- servletContext:若需要所有的servlet都能访问到,才使用这个域对象