Servlet之间数据共享

Servlet之间数据共享的实现方案

1、数据共享:OneServlet工作完毕之后,将产生的数据交给TwoServlet来使用

2、在Servlet规范中提供了四种数据共享方案:

        1)ServletContext接口

        2)Cookie类

        3)HttpSession接口

        4)HttpServletRequest接口

ServletContext接口

 1、介绍:

        1)来自于Servlet规范中的一个接口。在Tomcat中存在于servlet-api.jar

        在Tomcat中负责提供这个接口的实现类

        2)如果两个Servlet来自于同一个网站。彼此之间通过网站中的ServletContext

        实例对象来实现数据共享。

        3)开发人员习惯于将ServletContext对象称为【全局作用域对象】

    2、工作原理:

        每一个网站里面都存在一个全局作用域对象。

        这个全局作用于对象【相当于】一个Map

        在这个网站中OneServlet可以将一个数据存入到全局作用域对象中,当前网站中

        其他的Servlet此时都可以从全局作用域对象得到这个数据进行使用。

    3、全局作用域对象的声生命周期(不是自己创建的)

        1)在Http服务器启动的过程中,自动为当前网站在内存中创建一个全局作用域对象

        2)在Http服务器运行期间,一个网站只有一个全局作用域对象

        3)在Http服务器运行期间,全局作用域对象一直处于存活状态

        4)在Http服务器准备关闭的时候,负责将当前网站中全局作用域对象进行销毁处理

        ******全局作用域对象的生命周期贯穿网站的整个运行期间******

    4、命令实现:

        【同一个网站】OneServlet将数据分享给TwoServlet

        OneServlet{

            protected void doGet(HttpServletRequest request,HttpServletResponse response){

                //1、通过请求对象向Tomcat索要当前网站中的【全局作用域对象】

                ServletContext application=request.getServletContext();

                //2、将数据添加到全局作用域对象中作为【共享数据】

                application.setAttribute("key1","数据");

            }

        }

        TwoServlet{

            protected void doGet(HttpServletRequest request,HttpServletResponse response){

                //1、通过请求对象向Tomcat索要当前网站中的【全局作用域对象】

                ServletContext application=request.getServletContext();

                //2、从全局作用域对象得到指定关键字对应数据

                Object obj=application.getAttribute("key1");

            }

        }

代码展示

public class OneServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String s="abc";
        //通过请求对象获取全局作用域对象
        ServletContext application=request.getServletContext();
        //将数据添加到全局作用域对象中
        application.setAttribute("key1",s);
    }
}


public class TwoServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        PrintWriter out=null;
        //通过响应对象获取全局作用域对象
        ServletContext application=request.getServletContext();
        //通过全局作用对象来回去数据
        String s=(String)application.getAttribute("key1");
        response.setContentType("text/html");
        out=response.getWriter();
        System.out.println(s);
        out.print(s);
    }
}

Cookie类

1、介绍:

        1)Cookie是来自于Servlet规范中的一个工具类存在于Tomcat提供的servlet-api.jar

        2)如果两个Servlet来自于同一个网站,并且为同一个用户/浏览器提供服务,此时可以借助于

        Cookie对象进行数据共享

        3)Cookie存放当前用户的私人数据,在共享数据的过程中来提高服务质量

        4)在现实生活的场景中,Cookie相当于用户在服务端得到的【会员卡】

    2、相关原理:

        用户通过浏览器第一次向myWeb网站发送请求申请OneServlet。

        OneServlet在运行期间创建一个Cookie存储与当前用户相关的数据

        OneServlet工作完毕之后,【将Cookie写入到响应头中】来交还给

        当前浏览器。

        浏览器在收到这个响应包之后,将Cookie存储在浏览器的缓存中。

        一段时间之后,用户通过同一个浏览器再次向myWeb网站发送请求申请TwoServlet时。

        【浏览器需要无条件的将myWeb网站之前推送过来的Cookie,写入到请求头】发送过去

        此时TwoServlet在运行时,就可以通过读取请求头中Cookie中的信息,得到OneServlet

        提供的共享数据。

    3、实现命令:

        同一个网站中的OneServlet与TwoServlet借助于Cookie实现数据的共享方案

        OneServlet(HttpServletRequest request,HttpServletResponse response){

            protected void doGet{

                //创建一个Cookie对象,来保存共享数据(当前用户的共享数据)

                Cookie card=new Cookie("key1","abc");

                Cookie card1=new Cookie("key2","efg");

                ****Cookie相当于一个map

                ****一个Cookie中只能放一个键值对

                ****这个键值对的key和value只能是String

                ****键值对中的key不能是中文

                //将Cookie写入到响应头,交给浏览器

                request.addCookie(card);

                request.addCookie(card1);

                ....

            }

        }

        浏览器向myWeb网站发送请求请求访问TwoServlet----->请求包【url:/myWeb/two method:get】

                                                                【

                                                                    请求参数:***

                                                                    cookie key1=abc;key2=efg

                                                                】

                                                                【】

                                                                【】

        TwoServlet(HttpServletRequest request,HttpServletResponse response){

            protected void doGet{

                //调用请求对象从请求头得到浏览器返回的Cookie

                Cookie cookieArray=request.getCookies();

                //循环遍历数组得到每一个cookie

                for(Cookie card:cookieArray){

                    String key=card.getName();

                    String value=card.getValue();

                }

           }

        }

4、Cookie的销毁时机

        1)默认情况下,Cookie对象是存放在浏览器的缓存中。

        只有浏览器关闭,Cookie对象就被销毁。

        2)在手动设置的情况下,可以要求浏览器将接受的Cookie

        存放在客户端计算机的硬盘上。同时需要指定Cookie在硬盘

        上的存活时间,在存活时间范围内,关闭浏览器,关闭客户端

        计算机,关闭服务器,都不会导致Cookie被销毁。在存活时间

        到达时,Cookie自动从硬盘上被删除。

        cookie.setMaxAge(60);表示Cookie对象将在硬盘上存活60s

代码实现

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1 style="color: red" align="center">登录界面</h1>
<hr>
<form action="/myWeb/one" >
    <table align="center" 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="submit" />
                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                <input type="reset" value="reset" />
            </td>
        </tr>
    </table>
</form>
</body>
</html>

OnsServlet

package school.xauat.controller;

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;

public class OneServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String userName,money;
        //通过请求对象获取请求参数
        userName=request.getParameter("userName");
        money=request.getParameter("money");
        //创建Cookie对象
        Cookie cookie1=new Cookie("userName",userName);
        Cookie cookie2=new Cookie("money",money);
        //指定cookie对象在硬盘上存活1mins
        //cookie2.setMaxAge(60);
        //通过响应对象将Cookie对象放入响应头中
        response.addCookie(cookie1);
        response.addCookie(cookie2);
        //通过请求转发的方式访问index_1.html
        request.getRequestDispatcher("index_1.html").forward(request,response);
    }
}

index_1.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1 align="center" style="color:red;">点餐界面</h1>
<hr>
<form action="/myWeb/two">
    <table align="center" border="1px">
        <tr>
            <td><input type="radio" name="food" value="jiaozi" />饺子$30</td>
        </tr>
        <tr>
            <td><input type="radio" name="food" value="miantiao" />面条$25</td>
        </tr>
        <tr>
            <td><input type="radio" name="food" value="gaifan" />盖饭$20</td>
        </tr>
        <tr>
            <td><input type="submit" value="submit" /></td>
        </tr>
    </table>
</form>
</body>
</html>

TwoServlet

package school.xauat.controller;

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;
import java.io.PrintWriter;

public class TwoServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String food,userName = null;
        int money=0;
        Cookie newCookie=null;
        PrintWriter out=null;
        //通过请求对象获取请求参数
        food=request.getParameter("food");
        //获取请求头中的Cookie对象
        Cookie[] cookies=request.getCookies();
        //遍历cookies获取userName和money
        for(Cookie cookie:cookies){
            String key=cookie.getName();
            String value=cookie.getValue();
            if ("userName".equals(key)){
                userName=value;
            }
            if ("money".equals(key)){
                money=Integer.valueOf(value);
            }
        }
        response.setContentType("text/html;charset=utf-8");
        //通过响应对象获取输出流
        out=response.getWriter();
        //根据food的值进行不同的消费
        if ("jiaozi".equals(food)){
            if (money>=30){
                money-=30;
                newCookie=new Cookie("money",String.valueOf(money));
                out.print(userName+"您好,您本次消费30元,余额为:"+money);
                System.out.println(1);
            }else{
                out.print(userName+"您好,您的余额不足,余额:"+money);
            }
        }
        if ("miantiao".equals(food)){
            if (money>=25){
                money-=25;
                newCookie=new Cookie("money",String.valueOf(money));
                out.print(userName+"您好,您本次消费25元,余额为:"+money);
            }else{
                out.print(userName+"您好,您的余额不足,余额:"+money);
            }
        }
        if ("gaifan".equals(food)){
            if (money>=20){
                money-=20;
                newCookie=new Cookie("money",String.valueOf(money));
                out.print(userName+"您好,您本次消费20元,余额为:"+money);
            }else{
                out.print(userName+"您好,您的余额不足,余额:"+money);
            }
        }
        //如果消费成功,将cookie对象通过响应对象加入到响应头中
        if (newCookie!=null){
            response.addCookie(newCookie);
        }
    }
}

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集合存储共享数据,所以可以存储任意数量的共享数据

        4)参照物不同:

            Cookie相当于客户在服务端的【会员卡】数据量不大,数据类型单一

            HTTPSession相当于客户在服务端的【私人保险柜】

3、命令实现:

        同一个网站下(myWeb)OneServlet将数据传递给TwoServlet

        OneServlet{

            public void doGet(HttpServletRequest request,HttpServletResponse response){

                //调用请求对象向Tomcat索要当前用户在服务端的会话作用域对象

                HttpSession session=request.getSession();

                //将数据添加到用户的会话作用域对象

                session.setAttribute("key1",共享数据);

            }

        }

        浏览器访问/myWeb中的TwoServlet

        OneServlet{

            public void doGet(HttpServletRequest request,HttpServletResponse response){

                //通过请求对象向Tomcat索要当前用户在服务端的会话作用域对象

                HttpSession session=request.getSession();

                //从会话作用域对象中得到OneServlet提供的共享数据

                Object 共享数据=session.getAttribute("key1");

            }

        }

代码实现

下面用HttpSession接口实现购物车功能

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>购物车</title>
</head>
<body>
<h1 style="color:red;" align="center">京东</h1>
<hr>
<table align="center" border="1px">
    <thead>
    <tr>
        <td>商品名称</td>
        <td>商品单价</td>
        <td>介绍</td>
        <td>加入购物车</td>
    </tr>
    </thead>
    <tr>
        <td>Dell</td>
        <td>6500</td>
        <td>好东西</td>
        <td><a href="one?product=Dell">加入购物车</a></td>
    </tr>
    <tr>
        <td>Lenovo</td>
        <td>6000</td>
        <td>好东西</td>
        <td><a href="one?product=Lenovo">加入购物车</a></td>
    </tr>
    <tr>
        <td>MacBook</td>
        <td>7000</td>
        <td>好东西</td>
        <td><a href="one?product=MacBook">加入购物车</a></td>
    </tr>
    <tr>
        <td colspan="4" align="center">
            <a href="/myWeb/two">查看我的购物车</a>
        </td>
    </tr>

</table>
</body>
</html>

OneServlet

public class OneServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String product;
        //通过请求对象获取请求头中的请求参数
        product=request.getParameter("product");
        //通过请求对象向Tomcat服务器索要会话作用域对象
        HttpSession session = request.getSession();
        request.getSession(false);
        //将数据添加到会话作用域对象中
        Integer productNum=(Integer)session.getAttribute(product);
        if (productNum==null){
            session.setAttribute(product,1);
        }else{
            session.setAttribute(product,productNum+1);
        }
    }
}

  TwoServlet

public class TwoServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //通过请求对象获取会话作用域对象
        HttpSession session = request.getSession();
        //从会话作用域对象中读取所有的key值,存放在一个枚举中
        Enumeration<String> products = session.getAttributeNames();
        //循环遍历所有的共享数据
        while(products.hasMoreElements()){
            String product=products.nextElement();
            int productNum=(int)session.getAttribute(product);
            System.out.println("商品名称:"+product+"商品数量:"+productNum);
        }

    }
}

4、Http服务器如何将用户与HttpSession关联起来

        Cookie

5、getSession()和getSession(false)

        1)getSession()

            如果当前用户在服务端中已经拥有了自己的会话作用域对象

            要求Tomcat将这个会话作用域对象进行返回。

            如果当前用户在服务端尚未拥有自己的会话作用域对象。

            要求Tomcat为当前用户创建一个全新的会话作用域对象

        2)getSession(false)

            如果当前用户在服务端中已经拥有了自己的会话作用域对象

            要求Tomcat将这个会话作用域对象进行返回。

            如果当前用户在服务端尚未拥有自己的会话作用域对象。

            此时Tomcat将返回一个null

6、HttpSession销毁时机

        1、用户与HttpSession关联时使用的Cookie只能存放在浏览器的缓存中

        2、在浏览器关闭的时候,意味着用户与他的HttpSession关系被切断

        3、Tomcat无法检测浏览器何时关闭,因此在浏览器关闭时,并不会导致Tomcat将浏览器关联的HttpSession进行销毁

        4、为了解决这个问题,Tomcat会为每一个HttpSession对象设置【空闲时间】,这个空闲时间默认是30mins,如果当前HttpSession对象

            空闲时间达到了30mins,此时Tomcat认为用户已经放弃了自己的HttpSession,此时Tomcat就会销毁掉这个HeepSession。

7、HttpSession空闲时间的手动设置

        在当前网站下/web/WEB-INF/web.xml

        <session-config>

            <session-timeout>5</session-timeout><!--当前网站中每一个session最大的空闲时间是5mins-->

        </session-config>

HttpServletRequest接口

1、介绍:

        1)在同一个网站中,如果两个Servlet之间是通过【请求转发】的方式进行调用的

        他们彼此之间将共享同一个请求协议包,而一个请求协议包只对应一个请求对象,因此

        这个两个Servlet共享同一个请求对象,此时可以利用这个请求对象在两个Servlet之间

        实现数据共享。

        2)在请求对象实现Servlet之间的数据共享的功能时,开发人员将请求对象称为【请求作用域对象】

2、命令实现:

        OneServlet同过请求转发申请调用TwoServlet时,需要给TwoServlet提供共享数据

        OneServlet{

            public void doGet(HttpServletRequest request,HttpServletResponse response){

                //将数据添加到请求作用域对象中的attribute属性中

                request.setAttribute("key1",数据);//数据类型可以使任意类型的Object

                //向Tomcat申请调用TwoServlet

                //通过请求对象生成申请资源文件报告

                request.getRequestDispatcher("/two").forward(request,response);

            }

        }

        TwoServlet{

            public void doGet(HttpServletRequest request,HttpServletResponse response){

                //从当前请求对象中得到OneServlet写入的共享数据

                Object obj=request.getAttribute("key1");

            }

        }

代码实现

OneServlet

public class OneServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //将共享数据添加到请求作用域对象的attribute属性中
        request.setAttribute("key",500);
        //通过请求转发的方式调用TwoServlet
        RequestDispatcher report=request.getRequestDispatcher("/two");
        report.forward(request,response);
    }
}

TwoServlet

public class TwoServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //通过请求对象获取共享数据
        Integer num=(Integer) request.getAttribute("key");
        System.out.println(num);
    }
}

 

 

 

 

 

 

 

 

 

猜你喜欢

转载自blog.csdn.net/qq_45796208/article/details/108726200