前言:
多个Servlet之间数据共享实现方案:
1.数据共享:OneServlet工作完毕后,将产生数据交给TwoServlet来使用,这就叫做数据共享。
2.Servlet 规范中提供四种数据共享方案,通过一下四个接口/类来实现:
【ServletContext 接口】
【Cookie 类】
【HttpSession 接口】
【HttpServletRequest 接口】
ServletContext 接口:
1.介绍:
1)来自于Servlet规范中的一个接口,Tomcat负责提供这个接口实现类。
2)如果两个Servlet来自于同一个网站,就可以通过彼此之间网站的 ServletContext 实例对象实现数据共享。
3)开发人员习惯于将 ServletContext 对象称为【全局作用域对象】。
2.工作原理:
每一个网站都存在一个全局作用域对象,这个全局作用域对象相当于一个 Map ,在这个网站中 OneServlet 可以将一个数据存入到全局作用域对象中,这样当前网站中其他 Servlet 此时都可以从全局作用域对象得到这个数据进行使用。
3、工作原理图:
4.全局作用域对象生命周期:
【全局作用域对象生命周期贯穿网站整个运行期间】
1)在Http服务器启动过程中,自动为当前网站在内存中创建一个全局作用域对象。
2)在Http服务器运行期间时,一个网站只有一个全局作用域对象。
3)在Http服务器运行期间,全局作用域对象一直处于存活状态。
4)在Http服务器准备关闭时,负责将当前网站中全局作用域对象进行销毁处理。
5、举个栗子:
package com.burnyouth.controller;
import jakarta.servlet.*;
import jakarta.servlet.http.*;
import java.io.IOException;
public class OneServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//通过请求对象向Tomcat索要当前网站的全局作用域对象
ServletContext application = request.getServletContext();
//将数据添加到全局作用域对象中,作为共享数据
application.setAttribute(\"key\", 100);
}
}
package com.burnyouth.controller;
import jakarta.servlet.*;
import jakarta.servlet.http.*;
import java.io.IOException;
public class TwoServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//通过请求对象向Tomcat索要当前网站的全局作用域对象
ServletContext application = request.getServletContext();
//从全局作用域对象得到指定关键字对应的值
Integer integer = (Integer) application.getAttribute(\"key\");
System.out.println(integer);
}
}
Cookie:
1.介绍:
1)Cookie 是来自于 Servlet 规范中的一个工具类,存在于 Tomcat 提供的 servlet-api.jar 中。
2)如果两个 Servlet 来自于同一个网站,并且为同一个浏览器/用户提供服务,此时可以借助于 Cookie 对象进行数据共享。
3)Cookie存放当前用户的私人数据,在共享数据过程中提高服务质量。
4) 在现实生活场景中,Cookie相当于用户在服务端得到【会员卡】。
2.原理:
用户通过浏览器第一次向 MyWeb 网站发送请求申请,OneServlet 在运行期间创建一个 Cookie 存储当前用户相关数据,OneServlet工作完毕后,将 Cookie 写入到【响应头】交还给当前浏览器。浏览器收到响应包之后,会将 cookie 存储在浏览器的缓存中一段时间。在这段时间内,用户通过【同一个浏览器】再次向【myWeb网站】发送请求申请 TwoServlet 时。浏览器需要无条件的将 myWeb 网站之前推送过来的 Cookie,写入到请求头发送过去,此时TwoServlet在运行时,就可以通过读取请求头中的 cookie 信息,得到 OneServlet 提供的共享数据了。
3、工作原理图:
4、代码实现:
xml 文件:
<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<web-app xmlns=\"https://jakarta.ee/xml/ns/jakartaee\"
xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"
xsi:schemaLocation=\"https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd\"
version=\"5.0\">
<servlet>
<servlet-name>OneServlet</servlet-name>
<servlet-class>com.burnyouth.controller.OneServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>TwoServlet</servlet-name>
<servlet-class>com.burnyouth.controller.TwoServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>OneServlet</servlet-name>
<url-pattern>/one</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>TwoServlet</servlet-name>
<url-pattern>/two</url-pattern>
</servlet-mapping>
</web-app>
index.html 文件(开卡充值页面):
<!DOCTYPE html>
<html lang=\"en\">
<head>
<meta charset=\"UTF-8\">
<title>Title</title>
</head>
<body>
<font style=\"color: red;font-size: 50px\">新会员申请办卡</font>
<hr>
<form action=\"/myWeb/one\">
<table border=\"1px\">
<tr>
<td>用户名</td>
<td><input type=\"text\" name=\"userName\"></td>
</tr>
<tr>
<td>预存金额</td>
<td><input type=\"text\" name=\"money\"></td>
</tr>
<tr>
<td colspan=\"2\" align=\"center\">
<input type=\"submit\" value=\"申请办卡\">
<input type=\"reset\" value=\"清空\">
</td>
</tr>
</table>
</form>
</body>
</html>
index_2.html 文件(点餐划卡消费页面):
<!DOCTYPE html>
<html lang=\"en\">
<head>
<meta charset=\"UTF-8\">
<title>Title</title>
</head>
<body>
<font style=\"color: red;font-size: 40px\">点餐页面</font>
<hr>
<form action=\"/myWeb/two\">
食物类型:
<input type=\"radio\" name=\"food\" value=\"淀粉肠\">淀粉肠(1元)
<input type=\"radio\" name=\"food\" value=\"小饼\">小饼(1元)
<input type=\"radio\" name=\"food\" value=\"烤冷面\">烤冷面(3元)
<input type=\"submit\" value=\"划卡消费\">
</form>
</body>
</html>
OneServlet.java 文件(实现开卡充值功能):
package com.burnyouth.controller;
import jakarta.servlet.*;
import jakarta.servlet.http.*;
import java.io.IOException;
public class OneServlet 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 cookie1 = new Cookie(\"userName\",userName);
Cookie cookie2 = new Cookie(\"money\", money);
//发卡,将Cookie写入响应头交给浏览器
response.addCookie(cookie1);
response.addCookie(cookie2);
//通知浏览器将【点餐页面】内容写入到响应体交给浏览器
request.getRequestDispatcher(\"/index_2.html\").forward(request,response);
}
}
TwoServlet.java 文件(实现划卡消费功能):
package com.burnyouth.controller;
import jakarta.servlet.*;
import jakarta.servlet.http.*;
import java.io.IOException;
import java.io.PrintWriter;
public class TwoServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
int dianfenchang_money = 1;
int xiaobing_money = 1;
int kaolengmian_money = 3;
int money = 0;
int spending = 0,balance = 0;
String food,userName = null;
Cookie cards[] = null;
Cookie newCookie = null;
//切记,在得到输出流之前一定要设置正确的响应头的content-type属性
//response.setContentType(\"text/html;charset:utf-8\");
PrintWriter out = response.getWriter();
//读取请求头参数信息,得到用户点餐食物类型
food = request.getParameter(\"food\");
//读取请求中的Cookie
cards = request.getCookies();
//刷卡消费
for (Cookie card:cards) {
String key = card.getName();
String value = card.getValue();
if (\"userName\".equals(key)) {
userName = value;
} else if (\"money\".equals(key)) {
money = Integer.valueOf(value);
if (\"淀粉肠\".equals(food)) {
if (dianfenchang_money > money) {
out.print(\"用户:\"+userName+\"余额不足,请充值!\");
}else {
balance = money - dianfenchang_money;
newCookie = new Cookie(\"money\",balance+\"\");
spending = dianfenchang_money;
}
} else if (\"小饼\".equals(food)) {
if (xiaobing_money > money) {
out.print(\"用户:\" + userName + \"余额不足,请充值!\");
} else {
balance = money - xiaobing_money;
newCookie = new Cookie(\"money\",balance+\"\");
spending = xiaobing_money;
}
} else if (\"烤冷面\".equals(food)) {
if (kaolengmian_money > money) {
out.print(\"用户:\" + userName + \"余额不足,请充值!\");
} else {
balance = money-kaolengmian_money;
newCookie = new Cookie(\"money\",balance+\"\");
spending = kaolengmian_money;
}
}
}
}
//将用户的会员卡返还给用户
response.addCookie(newCookie);
//将消费记录写入到响应体中
out.print(\"用户:\"+userName+\",消费:\"+spending+\",余额:\"+balance);
}
}
5、Cookie销毁时机:
1)默认情况下,Cookie对象存放在浏览器的缓存中。因此只要浏览器关闭,Cookie对象就被销毁掉。
2)在手动设置情况下,可以要求浏览器将接收的 Cookie 存放在客户端计算机上硬盘上,同时需要指定 Cookie 在硬盘上存活时间。在存活时间范围内,关闭浏览器关闭客户端计算机,关闭服务器,都不会导致 Cookie 被销毁。在存活时间到达时,Cookie 自动从硬盘上被删除。
//指定cookie在硬盘中存活时间,要在cookie对象创建之后
cookie.setMaxAge(60); //cookie在硬盘上存活1分钟
//指定cookie在硬盘中存活时间,把cookie写入到响应头之前
HttpSession 接口:
1.介绍:
1)HttpSession 接口是来自于 Servlet 规范下的一个接口,其实现类由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 集合存储共享数据,所以可以存储任意数量共享数据。
4)【参照物】:
Cookie 相当于客户在服务端的【会员卡】。
HttpSession 相当于客户在服务端的【私人保险柜】。
3.HttpSession 工作原理图:
4、代码实现:
xml 文件:
<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<web-app xmlns=\"https://jakarta.ee/xml/ns/jakartaee\"
xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"
xsi:schemaLocation=\"https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd\"
version=\"5.0\">
<servlet>
<servlet-name>OneServlet</servlet-name>
<servlet-class>com.burnyouth.controller.OneServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>TwoServlet</servlet-name>
<servlet-class>com.burnyouth.controller.TwoServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>OneServlet</servlet-name>
<url-pattern>/one</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>TwoServlet</servlet-name>
<url-pattern>/two</url-pattern>
</servlet-mapping>
</web-app>
index.html 文件(操作购物车页面):
<!DOCTYPE html>
<html lang=\"en\">
<head>
<meta charset=\"UTF-8\">
<title>Title</title>
</head>
<body>
<table border=\"1px\">
<tr>
<td>商品名称</td>
<td>单价</td>
<td>供应商</td>
<td>操作</td>
</tr>
<tr>
<td>肥皂</td>
<td>5</td>
<td>印度</td>
<td><a href=\"/myWeb/one?goodsName=肥皂\">放入购物车</a> </td>
</tr>
<tr>
<td>圆珠笔</td>
<td>1</td>
<td>广源文体商店</td>
<td><a href=\"/myWeb/one?goodsName=圆珠笔\">放入购物车</a> </td>
</tr>
<tr>
<td>水杯</td>
<td>1000</td>
<td>上海迪士尼乐园</td>
<td><a href=\"/myWeb/one?goodsName=水杯\">放入购物车</a> </td>
</tr>
<tr align=\"center\">
<td colspan=\"4\">
<a href=\"/myWeb/two\">查看购物车</a>
</td>
</tr>
</table>
</body>
</html>
OneServlet.java 文件(实现将商品放入购物车功能):
package com.burnyouth.controller;
import jakarta.servlet.*;
import jakarta.servlet.http.*;
import java.io.IOException;
public class OneServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String goodsName;
//调用请求对象,获取请求头参数(得到商品名称)
goodsName = request.getParameter(\"goodsName\");
//调用请求对象,向Tomcat索要当前用户在服务器的私人保险柜
HttpSession session = request.getSession();
//将用户选购商品添加到当前用户的私人保险柜中
Integer goodsNum = (Integer) session.getAttribute(goodsName);
if (goodsNum == null) {
session.setAttribute(goodsName, 1);
} else {
session.setAttribute(goodsName,goodsNum+1);
}
}
}
TwoServlet.java 文件(实现查看购物车功能):
package com.burnyouth.controller;
import jakarta.servlet.*;
import jakarta.servlet.http.*;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;
public class TwoServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//调用请求对象,向Tomcat索要当前用户的私人保险柜
HttpSession session = request.getSession();
//将session中的所有key读取出来,存放到一个枚举对象中
Enumeration goodsNames = session.getAttributeNames();
while (goodsNames.hasMoreElements()) {
String goodsName = (String) goodsNames.nextElement();
int goodsNum = (int) session.getAttribute(goodsName);
System.out.println(\"商品名称:\"+goodsName+\",商品数量:\"+goodsNum);
}
}
}
5、Http 服务器如何将用户与 HttpSession 关联起来的?
6、getSession( ) 与 getSession(false):
1)getSession( ):
如果当前用户在服务端已经拥有了自己的私人储物柜,要求tomcat将这个私人储物柜进行返回;如果当前用户在服务端尚未拥有自己的私人储物柜,要求tocmat为当前用户创建一个全新的私人储物柜。
2)getSession(false):
如果当前用户在服务端已经拥有了自己的私人储物柜,要求tomcat将这个私人储物柜进行返回;如果当前用户在服务端尚未拥有自己的私人储物柜,此时Tomcat将返回null。
7、HttpSession销毁时机:
1)用户与 HttpSession 关联时使用的 Cookie 只能存放在浏览器缓存中。
2)在浏览器关闭时,意味着用户与他的 HttpSession 关系被切断。
3)由于 Tomcat 无法检测浏览器何时关闭,因此在浏览器关闭时并不会导致Tomcat将浏览器关联的 HttpSession 进行销毁。
4)为了解决这个问题,Tomcat为每一个HttpSession对象设置【空闲时间】,这个空闲时间默认为30分钟,如果当前 HttpSession 对象空闲时间达到30分钟。此时Tomcat认为用户已经放弃了自己的HttpSession,此时Tomcat就会销毁掉这个HttpSession。
8、如何手动设置 HttpSession 空闲时间:
当前网站/web/WEB-INF/web.xml:
<session-config>
<session-timeout>5</session-timeout> <!--当前网站中每一个session最大空闲时间5分钟-->
</session-config>
HttpServletRequest 接口实现数据共享:
1.介绍:
1) 在同一个网站中,如果两个Servlet之间通过【请求转发】方式进行调用,彼此之间共享同一个请求协议包。而一个请求协议包只对应一个请求对象,因此servlet之间共享同一个请求对象,此时可以利用这个请求对象在两个Servlet之间实现数据共享。
2) 在请求对象实现Servlet之间数据共享功能时,开发人员将请求对象称为【请求作用域对象】。
2.代码实现: 【OneServlet 通过请求转发申请调用 TwoServlet 时,需要给 TwoServlet 提供共享数据】
xml :
<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<web-app xmlns=\"https://jakarta.ee/xml/ns/jakartaee\"
xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"
xsi:schemaLocation=\"https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd\"
version=\"5.0\">
<servlet>
<servlet-name>OneServlet</servlet-name>
<servlet-class>com.burnyouth.controller.OneServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>TwoServlet</servlet-name>
<servlet-class>com.burnyouth.controller.TwoServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>OneServlet</servlet-name>
<url-pattern>/one</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>TwoServlet</servlet-name>
<url-pattern>/two</url-pattern>
</servlet-mapping>
</web-app>
OneServlet.java:
package com.burnyouth.controller;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
public class OneServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.将数据添加到请求作用域对象,作为共享数据
request.setAttribute(\"key1\", \"hello World\");
//2.代替浏览器,向Tomcat索要TwoServlet来完成剩余任务
request.getRequestDispatcher(\"/two\").forward(request, response);
}
}
TwoServlet.java:
package com.burnyouth.controller;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
public class TwoServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 从同一个请求作用域对象得到OneServlet写入到共享数据
String value = (String) request.getAttribute(\"key1\");
System.out.println(\"TwoServlet得到共享数据 \" + value);
}
}
来源:https://www.cnblogs.com/Burning-youth/p/16004533.html
本站部分图文来源于网络,如有侵权请联系删除。