• servlet学习(五)--HttpServletContext


    Servletcontext 对象

    ServletContext是一个全局的储存信息的空间,服务器开始就存在,服务器关闭才释放。为了方便大家理解,我们将ServletContext和Cookie、Session做一个简单对比,如下图:

    1 

    我们可以把ServletContext当成一个公用的空间,可以被所有的客户访问,如上图,A、B、C三个客户端都可以访问。

    WEB容器在启动时,它会为每个Web应用程序都创建一个对应的ServletContext,它代表当前Web应用,并且它被所有客户端共享。

    由于一个WEB应用中的所有Servlet共享同一个ServletContext对象,因此Servlet对象之间可以通过ServletContext对象来实现通讯。ServletContext对象通常也被称之为context域对象。公共聊天室就会用到它。

    当web应用关闭、Tomcat关闭或者Web应用reload的时候,ServletContext对象会被销毁

    ServletContext使用方法

     

    1、ServletContext对象如何得到

    this.getServletContext(); 
    this.getServletConfig().getServletContext();

    2、你可以把它想象成一张表,这个和Session非常相似:每一行就是一个属性,如下:

    名字(String)值(Object)
       
       


    添加属性:setAttribute(String name, Object obj);

    得到值:getAttribute(String name),这个方法返回Object

    删除属性:removeAttribute(String name)

    3、生命周期 

    ServletContext中的属性的生命周期从创建开始,到服务器关闭结束。

    一个快速入门的案例: 

    我们创建Servlet1和Servlet2,分别用于在ServletContext中创建和读取属性: 

    Servlet1的doGet方法为:

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        // 获取ServletContext对象的引用
        // 第一种方法
    
        ServletContext servletContext = this.getServletContext();
        // 第二种方法
        // ServletContext servletContext2 = this.getServletConfig().getServletContext();
        servletContext.setAttribute("name", "小明");
        out.println("将 name=小明  写入了ServletContext");
    }

    Servlet2的doGet方法为:

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        // 取出ServletContext的某个属性
        //1.首先获取到ServletContext
        ServletContext servletContext = this.getServletContext();
        //2.取出属性
        String name = (String)servletContext.getAttribute("name");
        out.println("name="+name);
    }

    以此访问Servlet1和Servlet2,我们可以分别看到输出如下:

    Servletcontext 对象 

     

    Servletcontext 对象 

    粗看之下,这个运行结果和Session,Cookie的应用似乎没什么区别,但事实上则完全不一样的。只要不关闭Tomcat或者reload该应用,当我们关闭当前的浏览器,或者是换一个浏览器,比如从360浏览器换到了IE浏览器再次访问Servlet2,我们依然可以看到这个结果!这就是和和Session,Cookie最大的不同了。之所以会造成这种不同,是因为ServletContext存在于服务器内存中的一个公共空间,它可以供所有的用户客户端访问。

    ServletContext应用

     

    1、多个Servlet可以通过ServletContext对象来实现数据间的共享

    类似于Session,通过ServletContext对象我们也可以实现数据共享,但值得注意的是,Session是只能在一个客户端中共享数据,而ServletContext中的数据是在所有客户端中都可以实现数据共享的。

    2、实现Servlet的请求转发

    之前我们学过的请求转发是通过request对象的: 

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

    这里要说明的是,ServletContext也可以实现请求转发: 

    this.getServletContext().getRequestDispatcher("/url").forward(request, response); 

    这两个转发效果是一样的。

    3、获取Web应用的初始化参数

    我们可以用<init-param>标签为servlet配置初始化参数,然后使用ServletConfig对象获取这些参数,假如有如下的MyServlet,它的配置为:

    <servlet>  
        <servlet-name>MyServlet</servlet-name>  
        <servlet-class>com.gavin.servlet.MyServlet</servlet-class>  
        <init-param>  
            <param-name>encoding</param-name>  
            <param-value>utf-8</param-value>  
        </init-param>  
    </servlet>  

    可以看到它配置了一个初始化参数:encoding=utf-8,那么我们在MyServlet的源代码中需要这样去得到这个参数:

    String encoding = this.getServletConfig().getInitParameter("encoding");

    注意,上述的参数配置方法只针对一个特定的Servlet有效,我们可以通过ServletContext来获取全局的、整个Web应用的初始化参数,全局的初始化参数是这样配置在web.xml文件中的:

    <!-- 如果希望所有的Servlet都可以使用该配置,则必须这么做 -->
    <context-param>
        <param-name>name</param-name>
        <param-value>gavin</param-value>
    </context-param>

    然后我们可以在任意一个Servlet中使用ServletContext获取这个参数:

    String name = this.getServletContext().getInitParameter("name");

     

    4、利用ServletContext对象读取资源文件(比如properties文件) 

    读取资源文件要根据资源文件所在的位置来决定,一般分为以下两种情况:

    4.1:文件在WebRoot文件夹下,即Web应用的根目录。这时候我们可以使用ServletContext来读取该资源文件。

    假设我们Web根目录下有一个配置数据库信息的dbinfo.properties文件,里面配置了name和password属性,这时候可以通过ServletContext去读取这个文件:

    // 这种方法的默认读取路径就是Web应用的根目录
    InputStream stream = this.getServletContext().getResourceAsStream("dbinfo.properties");
    // 创建属性对象
    Properties properties = new Properties();
    properties.load(stream);
    String name = properties.getProperty("name");
    String password = properties.getProperty("password");
    out.println("name="+name+";password="+password);

    4.2:如果这个文件放在了src目录下,这时就不能用ServletContext来读取了,必须要使用类加载器去读取。

    // 类加载器的默认读取路径是src根目录
    InputStream stream = MyServlet.class.getClassLoader().getResourceAsStream("dbinfo.properties")

    如果这个文件此时还没有直接在src目录下,而是在src目录下的某个包下,比如在com.gavin包下,此时类加载器要加上包的路径,如下:

    InputStream stream = MyServlet.class.getClassLoader().getResourceAsStream("com/gavin/dbinfo.properties")

    补充一点,ServletContext只有在读取的文件在web应用的根目录下时,才能获取文件的全路径。比如我们在WebRoot文件夹下有一个images文件夹,images文件夹下有一个Servlet.jpg图片,为了得到这个图片的全路径,如下:

    // 如何读取到一个文件的全路径,这里会得到在Tomcat的全路径
    String path = this.getServletContext().getRealPath("/images/Servlet.jpg");

    在网站开发中,有很多功能要使用ServletContext,比如 

    1. 网站计数器 

    2. 网站的在线用户显示 

    3. 简单的聊天系统

    总之,如果是涉及到不同用户共享数据,而这些数据量不大,同时又不希望写入数据库中,我们就可以考虑使用ServletContext实现。

    转自:https://www.w3cschool.cn/servlet/servlet-3ceg2p0t.html

    个人理解,如有错误,欢迎指正!
  • 相关阅读:
    dede list调用 内容模型 附件
    dedecms list标签调用附加表字段--绝对成功
    织梦系统站点首页、列表、文章页等页面点击数调用方法
    apache include 文件包含引用的方法 报错 [an error occurred while processing this directive]
    windows 2008 中IIS7.0以上如何设置404错误页面
    织梦Fatal error: Call to a member function GetInnerText()
    dedecms清空栏目后,新建ID不从1开始的解决方法
    js禁止
    AngularJs表单验证
    submile 安装,汉化,插件
  • 原文地址:https://www.cnblogs.com/gllegolas/p/11804105.html
Copyright © 2020-2023  润新知