JavaWeb-解析ServletCntext应用域

说明:

    本片文章主要描述的是ServletContext应用域,在Servlet的实现抽象类GenericServlet中有getServletContext方法,因此一个ServletContext可以通过调用此方法来获取ServletContext对象。通过阅读本篇博文可以了解到ServletContext在Servlet中的应用和他的详细信息

1、ServletContext是什么?理解ServletContext

Ⅰ 理解:ServletContext指的是一个Servlet的配置信息对象,只要在同一个webapp当中,只要在同一个应用当中,所有的Servlet对象都是共享同一个ServletContext对象的。

Ⅱ ServletContext对象在服务器启动阶段创建,在服务器关闭的时候销毁。这就是ServletContext对象的生命周期。ServletContext对象是应用级对象。

Ⅲ Tomcat服务器中有一个webapps,这个webapps下可以存放webapp,可以存放多个webapp,假设有100个webapp,那么就有100个ServletContext对象。但是,总之,一个应用,一个webapp肯定是只有一个ServletContext对象。

Ⅳ ServletContext被称为Servlet上下文对象。(Servlet对象的四周环境对象。)

Ⅴ 一个ServletContext对象通常对应的是一个web.xml文件。

2、使用生活中的例子理解ServletContext

    一个教室里有多个学生,那么每一个学生就是一个Servlet,这些学生都在同一个教室当中,那么我们可以把这个教室叫做ServletContext对象。那么也就是说放在这个ServletContext对象(环境)当中的数据,在同一个教室当中,物品都是共享的。比如:教室中有一个空调,所有的学生都可以操作。可见,空调是共享的。因为空调放在教室当中。教室就是ServletContext对象。

3、ServletContext对象的创建和销毁

    ServletContext对象的创建也是Tomcat服务器来完成的。启动webapp的时候创建的,ServletContext是一个接口,Tomcat服务器对ServletContext接口进行了实现。

也就是说在服务器启动的时候创建,服务器关闭的时候销毁。

4、ServletContext的常用方法

Ⅰ public String getInitParameter(String name); // 通过初始化参数的name获取value

Ⅱ public Enumeration< S t r i n g > getInitParameterNames(); // 获取所有的初始化参数的name

    以上两个方法是ServletContext对象的方法,这个方法获取的是什么信息?是以下的配置信息:

<context-param>
    <param-name>pageSize</param-name>
    <param-value>10</param-value>
</context-param>
<context-param>
    <param-name>startIndex</param-name>
    <param-value>0</param-value>
</context-param>

注意:
    以上的配置信息属于应用级的配置信息,一般一个项目中共享的配置信息会放到以上的标签当中。
    如果你的配置信息只是想给某一个servlet作为参考,那么你配置到servlet标签当中即可,使用ServletConfig对象来获取。

Ⅲ public String getContextPath();// 获取应用的根路径(非常重要),因为在java源代码当中有一些地方可能会需要应用的根路径,这个方法可以动态获取应用的根路径

Ⅳ public String getRealPath(String path);// 获取文件的绝对路径(真实路径)

Ⅴ public void log(String message);// 通过ServletContext对象也是可以记录日志
public void log(String message, Throwable t);

public class AServlet extends GenericServlet {
    @Override
    public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();

        //获取ServletContext对象
        ServletContext application = this.getServletContext();
        out.print("servletContext对象是:" + application + "<br>");


        //获取上下文的初始化配置参数
        Enumeration<String> initParameterNames = application.getInitParameterNames();
        while (initParameterNames.hasMoreElements()){

            //获取初始化参数中的param-name
            String name = initParameterNames.nextElement();
            //调用ServletContext对象的方法获取对应的value
            String value = application.getInitParameter(name);
            out.print(name + "=" +value + "<br>");
        }

        //获取servlet的根路径(项目部署在服务器起的名字)
        String contextPath = application.getContextPath();
        out.print("项目的根路径是:"+contextPath);


        //获取文件的绝对路径
        String realPath = application.getRealPath("/index.html");
        out.print("index页面的真实路径是:"+realPath+"<br>");

        //获取不在根目录下的文件的绝对路径
        String realPath1 = application.getRealPath("/common/new.html");
        out.print("index页面的真实路径是:"+realPath1+"<br>");


        //向ServletContext应用域中存数据
        User user = new User("Jack","123");

        application.setAttribute("userobj",user);

        //取数据
        Object userobj = application.getAttribute("userobj");

        //打印在浏览器(提示:也可以在别的Servlet中取数据,应用域中的数据时共享的)
        out.print(userobj+"<br>");
    }
}

5、Tomcat服务器的日志文件

lcatalina.2021-11-05.log 服务器端的java程序运行的控制台信息
localhost.2021-11-05.log ServletContext对象的log方法记录的日志信息存储到这个文件中。
localhost_access_log.2021-11-05.txt 访问日志

6、ServletContext(应用域)中实现存储数据

概述性理解内容

    ServletContext对象还有另一个名字:应用域(后面还有其他域,例如:请求域、会话域)

    如果所有的用户共享一份数据,并且这个数据很少的被修改,并且这个数据量很少,可以将这些数据放到ServletContext这个应用域中

为什么是所有用户共享的数据?
     不是共享的没有意义。因为ServletContext这个对象只有一个。只有共享的数据放进去才有意义。

为什么数据量要小?
    因为数据量比较大的话,太占用堆内存,并且这个对象的生命周期比较长,服务器关闭的时候,这个对象才会被销毁。大数据量会影响服务器的性能。占用内存较小的数据量可以考虑放进去。

为什么这些共享数据很少的修改,或者说几乎不修改?
     所有用户共享的数据,如果涉及到修改操作,必然会存在线程并发所带来的安全问题。所以放在ServletContext对象中的数据一般都是只读的。

     数据量小、所有用户共享、又不修改,这样的数据放到ServletContext这个应用域当中,会大大提升效率。因为应用域相当于一个缓存,放到缓存中的数据,下次在用的时候,不需要从数据库中再次获取,大大提升执行效率。

重点
存(怎么向ServletContext应用域中存数据)
public void setAttribute(String name, Object value); // map.put(k, v)
取(怎么从ServletContext应用域中取数据)
public Object getAttribute(String name); // Object v = map.get(k)
删(怎么删除ServletContext应用域中的数据)
public void removeAttribute(String name); // map.remove(k)

public class AServlet extends GenericServlet {
    @Override
    public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();

        //获取ServletContext对象
        ServletContext application = this.getServletContext();
        out.print("servletContext对象是:" + application + "<br>");
        
       //向ServletContext应用域中存数据
        User user = new User("Jack","123");

        application.setAttribute("userobj",user);

        //取数据
        Object userobj = application.getAttribute("userobj");

        //打印在浏览器(提示:也可以在别的Servlet中取数据,应用域中的数据时共享的)
        out.print(userobj+"<br>");
    }
}

------扩充内容

7、缓存机制

Ⅰ 堆内存当中的字符串常量池
     “abc” 先在字符串常量池中查找,如果有,直接拿来用。如果没有则新建,然后再放入字符串常量池。

Ⅱ 堆内存当中的整数型常量池
     [-128 ~ 127] 一共256个Integer类型的引用,放在整数型常量池中。没有超出这个范围的话,直接从常量池中取。

Ⅲ 连接池(Connection Cache)
     这里所说的连接池中的连接是java语言连接数据库的连接对象:java.sql.Connection对象。
     JVM是一个进程。MySQL数据库是一个进程。进程和进程之间建立连接,打开通道是很费劲的。是很耗费资源的。怎么办?可以提前先创建好N个Connection连接对象,将连接对象放到一个集合当中,我们把这个放有Connection对象的集合称为连接池。每一次用户连接的时候不需要再新建连接对象,省去了新建的环节,直接从连接池中获取连接对象,大大提升访问效率。
连接池
     最小连接数
     最大连接数
     连接池可以提高用户的访问效率。当然也可以保证数据库的安全性。

Ⅳ 线程池
    Tomcat服务器本身就是支持多线程的。
Tomcat服务器是在用户发送一次请求,就新建一个Thread线程对象吗?
    当然不是,实际上是在Tomcat服务器启动的时候,会先创建好N多个线程Thread对象,然后将线程对象放到集合当中,称为线程池。用户发送请求过来之后,需要有一个对应的线程来处理这个请求,这个时候线程对象就会直接从线程池中拿,效率比较高。
    所有的WEB服务器,或者应用服务器,都是支持多线程的,都有线程池机制。

Ⅴ redis
NoSQL数据库。非关系型数据库缓存数据库
向ServletContext应用域中存储数据,也等于是将数据存放到缓存cache当中了。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

皮皮皮皮皮皮皮卡乒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值