百木园-与人分享,
就是让自己快乐。

【JavaWeb-Servlet】笔记(3)--- 多个Servlet之间实现数据共享的四种方案: ServletContext / Cookie / HttpSession / HttpServletRequest

前言:


多个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、工作原理图:

【JavaWeb-Servlet】笔记(3)--- 多个Servlet之间实现数据共享的四种方案: ServletContext  / Cookie  / HttpSession  / HttpServletRequest

 

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、工作原理图:

 

【JavaWeb-Servlet】笔记(3)--- 多个Servlet之间实现数据共享的四种方案: ServletContext  / Cookie  / HttpSession  / HttpServletRequest

 

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 工作原理图:

 

【JavaWeb-Servlet】笔记(3)--- 多个Servlet之间实现数据共享的四种方案: ServletContext  / Cookie  / HttpSession  / HttpServletRequest

 

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 关联起来的?

 

【JavaWeb-Servlet】笔记(3)--- 多个Servlet之间实现数据共享的四种方案: ServletContext  / Cookie  / HttpSession  / HttpServletRequest

 

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
本站部分图文来源于网络,如有侵权请联系删除。

未经允许不得转载:百木园 » 【JavaWeb-Servlet】笔记(3)--- 多个Servlet之间实现数据共享的四种方案: ServletContext / Cookie / HttpSession / HttpServletRequest

相关推荐

  • 暂无文章