一、数据共享
1.数据共享概述
数据共享即为数据传递,比如 MyServletOne 这个类工作完毕后如何将数据传递给另一个Servlet类MyServletTwo,传递的过程就成为数据共享
2.数据共享解决方案
(1) ServletContext 接口
(2) Cookie 类
(3) HttpSession 接口
(4) HttpServletRequest 接口
二、ServletContext 接口
1.介绍
(1) 来自于Servlet规范中一个接口,在Tomcat中存在servlet-api.jar,在Tomcat中负责提供这个接口实现类。
(2) 如果两个Servlet 来自于同一个网站,彼此之间可以通过网站的ServletContext实例对象实现数据共享
(3) 我们习惯于将ServletContext 对象称为全局作用域对象
2.原理
每一个网站都存在一个全局作用域对象。这个全局作用域对象相当于一个Map.
在这个网站中MyServletOne可以将一个数据存入到全局作用域对象,当前网站中其他Servlet此时都可以从全局作用域对象得到这个数据进行使用。
3.生命周期
(1) 在Http服务器启动过程中,自动为当前网站在内存中创建一个全局作用域对象。
(2) 在Http服务器运行期间时,一个网站只有一个全局作用域对象。
(3) 在Http服务器运行期间,全局作用域对象一直处于存活状态。
(4) 在Http服务器准备关闭时,负责将当前网站中全局作用域对象进行销毁处理。
全局作用域对象生命周期贯穿网站整个运行期间
4.实现命令
MyServletOne doGet方法中:
ServletContext application = request.getServletContext();//1.通过请求对象向Tomcat索要当前网站中全局作用域对象
application.setAttribute("key",data);//2.将数据添加到全局作用域对象作为共享数据
MyServletTwo doGet方法中:
ServletContext application = request.getServletContext();//1.通过请求对象向Tomcat索要当前网站中的全局作用域对象
Object data = application.getAttribute("key");//2.从全局作用域对象得到指定关键字对应数据
5.代码实例
MyServletOne
package controller;
import jakarta.servlet.*;
import jakarta.servlet.http.*;
import jakarta.servlet.annotation.*;
import java.io.IOException;
@WebServlet(name = "MyServletOne", value = "/one")
public class MyServletOne extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext application = request.getServletContext();
application.setAttribute("key", 100);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
MyServletTwo
package controller;
import jakarta.servlet.*;
import jakarta.servlet.http.*;
import jakarta.servlet.annotation.*;
import java.io.IOException;
@WebServlet(name = "MyServletTwo", value = "/two")
public class MyServletTwo extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext application = request.getServletContext();
Integer num = (Integer) application.getAttribute("key");
System.out.println(num);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
我们启动Tomcat服务器,在浏览器中先打开MyServletOne,再打开MyServletTwo,结果如下图所示
三、Cookie 类
1.介绍
(1) Cookie来自于Servlet规范中一个工具类,存在于Tomcat提供servlet-api.jar中。
(2) 如果两个Servlet来自于同一个网站,并且为同一个浏览器/用户提供服务,此时借助于Cookie对象进行数据共享。
(3) Cookie存放当前用户的私人数据,在共享数据过程中提高服务质量
2.原理
用户通过浏览器第一次向myWeb网站发送请求申请MyServletOne。MyServletOne在运行期间创建一个Cookie存储与当前用户相关数据MyServletOne工作完毕后,将Cookie写入到响应头交还给当前浏览器。浏览器收到响应响应包之后,将Cookie存储在浏览器的缓存当中。一段时间之后,用户通过同一个浏览器再次向myWeb网站发送请求申请MyServletTwo时,浏览器需要无条件地将myWeb网站之前推送过来的Cookie,写入到请求头发送过去此时MyServletTwo在运行时,就可以通过读取请求头中Cookie中信息,得到MyServletTwo提供的共享数据。
3.实现命令
在MyServletOne doGet方法中:
Cookie c1 = new Cookie("key1", "abc");//1.创建Cookie对象, 保存共享数据
Cookie c2 = new Cookie("key2", "def");//Cookie相当于Map, 一个Cookie只能存放一个键值对, 并且键和值类型只能为String
response.add(c1);//2. 将Cookie写入响应头, 交给浏览器
response.add(c2);
在MyServletTwo doGet方法中:
Cookie cArray[] = request.getCookies();
for (Cookie c : cArray) {
String key = c.getName();
String value = c.getValue();
System.out.println(key+ " : " + value);
}
4.Cookie销毁时机
(1) 在默认情况下,Cookie对象存放在浏览器的缓存中。因此只要浏览器关闭,Cookie对象就被销毁掉。
(2) 在手动设置情况下,可以要求浏览器将接收的Cookie存放在客户端计算机上硬盘上,同时需要指定Cookie在硬盘上存活时间。在存活时间范围内,关闭浏览器,关闭客户端计算机,关闭服务器,都不会导致Cookie被销毁。在存活时间到达时,Cookie自动从硬盘上被删除。
Cookie cookie = new Cookie();
cookie.setMaxAge(60);//在硬盘上存活一分钟
5.代码实例
模拟用户餐馆点餐刷卡支付的流程
MyServletOne:
package controller;
import jakarta.servlet.*;
import jakarta.servlet.http.*;
import jakarta.servlet.annotation.*;
import java.io.IOException;
@WebServlet(name = "MyServletOne", value = "/one")
public class MyServletOne extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username, money;
username = request.getParameter("username");
money = request.getParameter("money");
Cookie c1 = new Cookie("username", username);
Cookie c2 = new Cookie("money", money);
response.addCookie(c1);
response.addCookie(c2);
request.getRequestDispatcher("/order.html").forward(request, response);
response.sendRedirect("/order.html");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
MyServletTwo:
package controller;
import jakarta.servlet.*;
import jakarta.servlet.http.*;
import jakarta.servlet.annotation.*;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet(name = "MyServletTwo", value = "/two")
public class MyServletTwo extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
int dumpling = 30;
int rice = 2;
int noodle = 15;
int money = 0, balance = 0, expense = 0;
String meal, username = null;
Cookie cookieArray[] = null;
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
Cookie c = null;
meal = request.getParameter("meal");
cookieArray = request.getCookies();
for (Cookie cookie : cookieArray) {
String key = cookie.getName();
String value = cookie.getValue();
if ("username".equals(key)) {
username = value;
} else if ("money".equals(key)) {
money = Integer.valueOf(value);
if ("dumpling".equals(meal)) {
if (dumpling > money) {
out.print("user : " + username + "doesn't have enough money");
} else {
c = new Cookie("money", (money - dumpling) + "");
expense = dumpling;
balance = money - dumpling;
}
}
} else if ("noodle".equals(meal)) {
if (noodle > money) {
out.print("user : " + username + "doesb't have enough money");
} else {
c = new Cookie("money", (money - noodle) + "");
expense = noodle;
balance = money - noodle;
}
} else if ("rice".equals(meal)) {
if (rice > money) {
out.print("user : " + username + " does‘t have enough money");
} else {
c = new Cookie("money", (money - rice) + "");
expense = rice;
balance = money - rice;
}
}
}
response.addCookie(c);
out.print("user : " + username + "you have take " + expense + " yuan " + " balance :" + balance);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<center>
<font style="color:red;font-size:40px">新用户申请开卡</font>
<form action="/myWeb/one">
<table border="2">
<tr>
<td>用户名</td>
<td><input type="text" name="userName"/></td>
</tr>
<tr>
<td>预存金额</td>
<td><input type="text" name="money"/></td>
</tr>
<tr>
<td><input type="submit" value="申请开卡"/></td>
<td><input type="reset" /></td>
</tr>
</table>
</form>
</center>
</body>
</html>
order.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<center>
<font style="color:red;font-size:40px">order</font>
<form action="/myWeb/two">
食物类型:<input type="radio" name="meal" value="dumpling"/>dumpling(30yuan)
<input type="radio" name="meal" value="noodle"/>noodle(20yuan)
<input type="radio" name="meal" value="rice"/>rice(2yuan)<br/>
<input type="submit" value="consuming by card">
</form>
</center>
</body>
</html>
流程如下
四、HttpSession 接口
1.介绍
(1) HttpSession接口来自于Servlet规范下一个接口,其存在于Tomcat中servlet-api.jar ,其实现类由Http服务器提供。Tomcat提供实现类存在于servlet-api.jar。
(2) 如果两个Servlet来自于同一个网站,并且为同一个浏览器/用户提供服务,此时借助于HttpSession对象进行数据共享。
(3) 我们通常习惯于将HttpSession 接口修饰的对象称为会话作用域对象
2.HttpSession 与 Cookie 的区别
(1) 存储位置:
Cookie:存放在客户端计算机(浏览器内存/硬盘)
HttpSession:存放在服务端计算机内存
(2) 数据类型:
Cookie对象存储共享数据类型只能是String
HttpSession对象可以存储任意类型的共享数据Object
(3) 数据数量:
一个Cookie对象只能存储一个共享数据
HttpSession使用map集合存储共享数据,所以可以存储任意数量共享数据
3.实现命令
在MyServletOne 的 doGet方法中:
HttpSession session = request.getSession();//1. 调用请求对象想Tomcat索要HttpSession对象
session.setAttribute("key1", 共享数据);//2. 将数据添加到HttpSession中
在MyServletTwo 的 doGet方法中:
HttpSession session = request.getSession();
Object 共享数据 = session.getAttribute("key1");
4.原理
当用户第一次访问Servlet时,服务器端会给用户创建一个独立的Session,并且生成一个SessionID,这个SessionID在响应浏览器的时候会被装进cookie中,从而被保存到浏览器中。当用户再一次访问Servlet 时,请求中会携带着cookie中的SessionID去访问,服务器会根据这个SessionID去查看是否有对应的Session对象,有就拿出来使用,没有就创建一个Session
5.getSession() 与 getSession(false)
(1) getSession() :
如果有对应的Session对象,则返回此对象。如果没有,则新建个Session对象
(2) getSession(false) :
如果有对应的Session对象,则返回此对象。如果没有,则返回null
6.HttpSession销毁时机
(1) 用户与HttpSession关联时使用的Cookie只能存放在浏览器缓存中。
(2) 在浏览器关闭时,意味着用户与他的HttpSession关系被切断。
(3) 由于Tomcat无法检测浏览器何时关闭,因此在浏览器关闭时并不会导致Tomcat将浏览器关联的HttpSession进行销毁。
(4) 为了解决此问题,Tomcat为每一个HttpSession对象设置空闲时间,这个空闲时间默认30分钟,如果当前HttpSession对象空闲时间达到30分钟,此时Tomcat认为用户已经放弃了自己的HttpSession,此时Tomcat就会销毁掉这个HttpSession
如何手动设置HttpSession的空闲时间
在web.xml文件下插入
<session-config>
<session-timeout>5</sesstion-timeout><!--当前网站中每一个session最大空闲时间5分钟-->
<session-config>
五、HttpServletRequest 接口
1.介绍
(1) 在同一个网站中,如果两个Servlet之间通过请求转发方式进行调用,彼此之间共享同一个请求协议包。而一个请求协议包只对应一个请求对象,因此Servlet之间共享同一个请求对象,此时可以利用这个请求对象在两个Servlet之间实现数据共享。
(2) 请求对象实现Servlet之间数据共享功能时,我们通常将请求对象称为请求作用域对象
2.命令实现
MyServletOne 通过请求转发调用 MyServletTwo 时,需要给 MyServletTwo 提供共享数据。
在MyServletOne 的doGet方法中
request.setAttribute("key1", data);//将数据添加到请求作用域对象的attribute
request.getRequestDispatcher("/two").forward(request, response);
在MyServletTwo 的doGet方法中
Object data = request.getAttribute("key1");