JavaWeb 学习笔记(四) ServletContext

ServletContext

一个项目只有ServletContext一个对象!所以在创建这个对象时经常起application这个名字。多个Servlet获取的是唯一的这个对象。它可以给多个Servlet传递数据,将多个Servlet串在一起,所以称之为上下文对象。特性:与天地同寿!与Tomcat同生共死

1. ServletContext概述

服务器会为每个应用创建一个ServletContext对象:

  • ServletContext对象的创建是在服务器启动时完成的
  • ServletContext对象的销毁是在服务器关闭时完成的

ServletContext对象的作用是在整个Web应用的动态资源之间共享数据。例如,AServlet向ServletContext对象中保存一个值,然后咋BServlet中就可以获取这个值了,这就是数据共享。

2. 获取ServletContext对象

在Servlet中获取ServletContext对象:

  • 在init()方法中的servletConfig:ServletContext context = getServletConfig().getServletContext();ServletConfig类的getServletContext()方法来获取;

在GenericServlet或HttpServlet中获取ServletContext对象:

  • 这两个类中有写好的获取ServletContext对象的方法,可以直接使用this.getServletContext()方法;

3. 域对象的功能

ServletContext是JavaWeb四大域对象之一:

  • PageContext
  • ServletContext
  • HttpSession
  • ServletRequest

域对象就是在多个Servlet中传递数据的!所有域对象都有保存数据的功能,因为域对象的内部只有一个Map来存储数据,下面是ServletContext对象用来操作数据的方法(内部其实就是一个Map):

  • void setAttribute(String name,Object value):用来存储一个对象,也可以称之为存储一个域属性,例如:servletContext.setAttribute("xxx","XXX"),在ServletContext中保存了一个域属性,域属性名称为xxx,域属性的值为XXX。请注意,如果多次调用该方法,并且使用相同的name,那么就会覆盖上一次的值,这就是Map的特性;
  • Object getAttribute(String name)用来获取ServletContext中的数据,在获取之前要先存储才行。例如:String value = (String)servletContext.getAttribute("xxx");
  • void removeAttribute(String name):用来移除ServletContext中的域属性,参数不存在,则什么都不做;
  • Enumeration getAttributeNames():返回所有域属性的名称;

考虑一个这样的项目:有两个Servlet,一个向ServletContext中存数据,另外一个取出数据,再分两个请求:先请求第一个,再请求第二个;
FServlet用来存储:

public class FServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        /*
        1.获取ServletContext对象
        2.调用其setAttribute方法来保存数据
         */      getServletContext().setAttribute("name","张三!");
    }
}

GServlet用来取出:

public class GServlet extends HttpServlet {
    /*
    1.获取ServletContext对象
    2.取出其中的数据
     */

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String s = (String) getServletContext().getAttribute("name");
        System.out.println("name"+": "+s);
    }
}

打开浏览器在地址栏依次输入两个Servlet的URL,然后在GServlet上刷新四次页面就可以看到从ServletContext对象中取出的数据:
这里写图片描述

4. 获取应用初始化参数

  • Servlet也可以获取初始化参数,但它是局部的参数;也就是说一个Servlet只能获取自己的初始化参数,不能获取别人的!
  • 可以配置公共的初始化参数,为所有的Servlet而用!这就需要ServletContext来获取

还可以使用ServletContext来获取在web.xml文件中配置的应用初始化参数!注意:应用初始化参数与Servlet初始化参数不同;
在web.xml中添加一项如下:

<context-param>
        <param-name>context-name</param-name>
        <param-value>context-value</param-value>
</context-param>

在EServlet中写如下代码:

public class EServlet extends HttpServlet {

    /*
    演示ServletContext获取公共的初始化参数
     */

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        /*
        1.获取ServletContext对象
        2.获取公共初始化参数
         */
        String value = getServletContext().getInitParameter("context-name");
        System.out.println(value);
    }
}

就可以看到公共初始化参数了(由参数的名字返回参数的值):
这里写图片描述

5. 获取资源相关方法

(1)
这里写图片描述

  1. 获取真实路径(重要):还可以使用ServletContext对象来获取web应用下的资源,例如在跟目录下创建一个a.txt文件,现在想在Servlet中获取这个资源,就可以使用ServletContext对象来获取
    • 获取a.txt的真实路径:String realPath = servletContext.getRealPath("a.txt");则realPath值为a.txt的绝对路径;
    • 获取b的真实路径:String realPath = servletContext.getRealPath("/WEB-INF/b.txt");

方法演示1获取a.txt真实路径:

public class EServlet extends HttpServlet {

    /*
    获取资源路径
     */

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        /*
        1.获取ServletContext对象
        2.获取资源路径
         */
        String s = getServletContext().getRealPath("a.txt");
        System.out.println(s);
    }
}

运行结果:
这里写图片描述

方法演示2获取b.txt真实路径(只有名称改变一下):

String s = getServletContext().getRealPath("/WEB-INF/b.txt");

运行结果:
这里写图片描述

(2)获取资源流:不仅可以获取资源路径,还可以资源流的形式获取数据

  • 获取a.txt的资源流:InputStream in = servletContext.getResourceAsStream("a.txt");
  • 获取b.txt的资源流:InputStream in = servletContext.getResourceAsStream("/WEB-INF/b.txt");

有两种方式与输入流关联:

 protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
        String s = getServletContext().getRealPath("/WEB-INF/b.txt");
        System.out.println(s);
        /*
        两种方式获取这个资源
         */
        InputStream in = new FileInputStream("s");
        InputStream in1 = getServletContext().getResourceAsStream("/WEB-INF/b.txt");

(3)获取指定目录下所有资源路径

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Set<String> path = this.getServletContext().getResourcePaths("/WEB-INF");
        System.out.println(path);
    }
}

这就可以直接查看这个文件夹下的所有东西:

这里写图片描述

练习:访问量统计

一个项目中所有资源被访问都要对访问量进行累加(计数器):

  • 创建一个int类型的计数器用来统计访问量,然后保存到ServletContext的域中!这样可以保证所有的Servlet都可以访问到
  • 当本站被第一次访问时,创建这个计数器并设置为1,保存在ServletContext的域中
  • 在以后的访问中,就从ServletContext的对象中获取并加1存储
public class EServlet extends HttpServlet {


    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        Integer count = (Integer)getServletContext().getAttribute("count");
        if (count==null)
            count = 1;
        else
            count++;
        getServletContext().setAttribute("count",count);
        resp.setContentType("text/html;charset=utf-8");
        resp.getWriter().print("<h1>本页面一共被访问"+count+"次!</h1>");
    }
}

当第一次访问时:
这里写图片描述

刷新两次以后:
这里写图片描述

获取类路径下的资源

在src文件夹中有a.txt文件,想要读取其中的数据:由于项目src文件夹中东西会被拷贝到WEB-INF的classes文件夹中,所以路径直接写就可以

public class EServlet extends HttpServlet {

    /*
    获取资源路径
     */

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        ClassLoader ca = getClass().getClassLoader();
        //ca.getResourceAsStream("a.txt");返回的是一个InputStream流
        BufferedReader bufr = new BufferedReader(new InputStreamReader(ca.getResourceAsStream("a.txt");));
        String s = null;
        while((s=bufr.readLine())!=null){
            System.out.println(s);
        }
    }
}

结果展示:

这里写图片描述

这里写图片描述

本人是菜鸟一枚,当做学习笔记写博客。谢谢各路大咖驻足审阅

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值