Servlet预加载实现手动添加全局参数

Servlet生命周期第一步,也就是init()函数,在此函数中,完成了各种数据的初始化,当然也包括参数初始化,也就是InitParam

当我们取初始化参数的时候,代码如下

    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Enumeration<String> e = this.getServletContext().getInitParameterNames();
        while (e.hasMoreElements()) {
            System.out.println(e.nextElement());
        }

        System.out.println("---------------------------------------");

        Enumeration<String> ee = this.getServletConfig().getInitParameterNames();
        while (ee.hasMoreElements()) {
            System.out.println(ee.nextElement());
        }
    }

也就是,初始化参数,实在init()中就被初始化,并实现了枚举接口Enumeration。

当这个枚举类型的对象(其实也就是初始化参数集合)被创建后,就无法再次添加了。

当我们在doget()函数中,想要再度添加全局参数的时候,就会报错。

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

        //添加全局参数,报错。
        this.getServletContext().setInitParameter("test", "test");

        Enumeration<String> e = this.getServletContext().getInitParameterNames();
        while (e.hasMoreElements()) {
            System.out.println(e.nextElement());
        }

        System.out.println("---------------------------------------");

        Enumeration<String> ee = this.getServletConfig().getInitParameterNames();
        while (ee.hasMoreElements()) {
            System.out.println(ee.nextElement());
        }
    }

错误一句话:Initialization parameters cannot be set after the context has been initialized

翻译过来就是说:已被初始化后的初始化参数集合,不能被设置。

好了,这么说,那这个this.getServletContext().setInitParameter()函数,存在的意义是什么呢?

从错误可以看出,这句话,必须要在init()函数初始化完毕这个 初始化参数集合(也就是上述说的,Enumeration接口对象)之前,才能设置初始化参数。

如何实现呢?

这时,我们的servlet预加载,就要闪亮登场了。

首先webl.xml中中的load-on-startup,设置一个大于等于0的数即可,我设置为1(数越低,优先级越高。值为负,不预加载。)

    <servlet>
        <servlet-name>Test</servlet-name>
        <servlet-class>cn.maiqiu.servlet.Test</servlet-class>
        <init-param>
            <param-name>city</param-name>
            <param-value>xian</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>Test</servlet-name>
        <url-pattern>/Test</url-pattern>
    </servlet-mapping>

此时,当服务器启动的时候,就会把这个servlet给加载了。

加载也就是说,创建了servlet对象,并且执行了init()方法。

重点:此时,刚启动服务器,就要加载这个servlet并且执行init()函数,那么,我们重写这个init()函数

    @Override
    public void init() throws ServletException {
        System.out.println("这个servlet预加载");
        //预加载之后,才可以操作初始化的值
        this.getServletContext().setInitParameter("test", "test");
    }

此时,服务器启动,为web项目创建servletcontext,并且立刻创建这个预加载的servlet并且执行init()函数,此时往servletContext中添加初始化参数,

就不会报错了。

xml中全局参数和预加载servlet方式读取全局参数顺序测试

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <context-param>
        <param-name>birthday</param-name>
        <param-value>0424</param-value>
    </context-param>

    <servlet>
        <servlet-name>Test</servlet-name>
        <servlet-class>cn.maiqiu.servlet.Test</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>Test</servlet-name>
        <url-pattern>/Test</url-pattern>
    </servlet-mapping>
</web-app>

此时我的web.xml中,有一个全局参数,叫做birthday。

另外我的预加载的servlet,也就是Test中重写Servlet接口中的init()函数,如上上图所示,

使用代码添加了一个全局参数,test。

此时,我们尝试在doGet()函数中,测试读取到的参数顺序。

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

        Enumeration<String> e = this.getServletContext().getInitParameterNames();
        while (e.hasMoreElements()) {
            System.out.println(e.nextElement());
        }
    }

输出结果:

birthday
test

结论:servlet预加载,在init()方法中,可以实现代码添加初始化参数。

读取顺序,servletContext先读取xml中的全局参数,再读取init()方法中的代码添加的全局参数。

 

原文地址:https://www.cnblogs.com/zh1996/p/10353387.html

时间: 2024-08-01 11:56:36

Servlet预加载实现手动添加全局参数的相关文章

苹果cms如何添加播放器预加载和缓冲广告

1,来到系统后台>>系统>>播放器参数设置  可以看到添加预加载和缓冲广告的输入框.文件格式为html 自己写一个html的网页上传到网站进行调用即可.链接前面不要加http或是htpps .还可以设置预加载广告的时长. 2,如果不会写html广告单页的话可以参照下面的简单模板来填写下,首先在桌面新建一个txt文本把这些代码复制到文本里面从“①填写自己要加载的网址”开始修改到⑥图片高度,图片边框,高度和宽度数值填写为0-1000的数字.修改完后把txt文本格式修改为html格式即可

ViewPager的刷新、限制预加载、缓存所有

[框架]: 公共部分:左侧菜单.TitleBar.RadioGroup(3个RadioButton:X.Y.Z) 选择X页面:指示器+ViewPager [要达成的效果]: (1)左侧选择A,进入X页面,X1联网刷新页面,此时禁止X2预加载—>滑动到X2页面,X2才联网刷新—>X3—>X4: (2)从X4再滑到X3.X2.X1时,X1.X2.X3不需要再次刷新,假设停留在X2页面: (3)左侧再点选择B,或者先点Y再点选择B再点X,这时候X2联网刷新: (4)X2页面滑到X1.X3.X4

前端资源预加载并展示进度条

我们经常会看到,一些站点在首次进入的时候会先显示一个进度条,等资源加载完毕后再呈现页面,大概像这样: 然后整个页面的操作就会非常流畅,因为之后没必要再等待加载资源了.尤其是在移动端,或者是页游中,这样做能避免页面出现白屏(等待加载图片),很大程度提升用户体验.那这种技术是如何实现的呢?其实非常简单,本文就来从基础细节探究一番. 为什么需要资源预加载 大多时候,我们的页面并不是一次渲染完毕的,而是随着用户的操作,不断修改DOM节点,如果你动态插入了一个图片节点,那么浏览器要马上发一个http请求,

基于spring的web项目启动时预加载数据到ServletContext

1.要在web启动时预加载数据到ServletContext,实现方法有很多,一种比较简单的方案就是: 1)新建一个bean,定义其初始化方法: <bean id="beanId" init-method="初始化方法" />或者使用@PostConstruct注解到初始化方法上面 2)获取ServletContext实例对象,如何获取呢? 方法1: @Autowired private ServletContext application; 方法2:

Promise实现多图预加载

Promise正如它的中文意思"承诺"一样,保存着未来会发生事件(一般为异步操作).Promise避免了"回调地狱",写法更加接近同步操作.说到同步,我更加喜欢async.await,它们书写更贴近同步操作. 图片加载往往是异步的,如果有操作需要等到所有的图片加载完之后再执行,这时候就需要不断的监听所有图片的加载情况. ES5 利用ES5实现多图预加载,可以通过计数器判断有多少图片加载完成. var count = 0, // 计数器 imgs = []; /* *

图片预加载和懒加载

1.什么是预加载? 提前加载图片,当用户需要查看时可直接从本地缓存中渲染. 2:什么是懒加载? 延迟加载图片,当用户需要的时候再去加载图片 当我们访问一些类似电商网站,遇到图片很多情况下,需要浏览器去下载这些图片,遇到网速比较慢的时候,用户等待的时间特别长,造成很不好的用户体验.这样的话,就有可能导致一部分的用户没有耐心,而丢失这部分用户. 图片的预加载是提升用户体验而损失性能的一种做法,而懒加载的性能就比较好,所以将两个结合起来放到web程序中是一种不错的选择. 预加载 Image 对象在客户

如何设置打开PL/SQL预加载之前的sql文本内容

笑谈:记得在初次使用PL/SQL的时候,投诉的人给了我一个sql文本,我的做法是用文本文档打开, ctrl + a ,ctrl + c,ctrl + v 或者是在PL/SQL里新建一个"SQL窗口",右键==>载入,选择 sql文本就可以加载进来,但是当下次重新打开PL/SQL的时候,依旧如此,突然有一天,看到别人 刚打开PL/SQL,就唰唰的,让我眼前一亮,我开始为我之前浪费的时间而忏悔...... 描述:每次在打开pl/sql的时候,都要手动的将已经写好的sql加载进来,比较

ViewPager+Fragment取消预加载(延迟加载)

在项目中,都或多或少地使用的Tab布局,所以大都会用到ViewPager+Fragment,但是Fragment有个不好或者太好的地方.例如你在ViewPager中添加了三个Fragment,当加载ViewPager中第一个Fragment时,它会默认帮你预先加载了第二个Fragment,当你加载第二个Fragment时,它会帮你加载第三个Fragment.这样虽然有时很好,但是用户只需看一个Fragment时,我们就做了一些多余工作加载了第二个Fragment.在这只需要取消Fragment的

用javascript预加载图片、css、js的方法研究

预加载的好处可以让网页更快的呈现给用户,缺点就是可能会增加无用的请求(但图片.css.js这些静态文件可以被缓存),如果用户访问的页面里面的css.js.图片被预加载了,用户打开页面的速度会快很多,提升用户体验.在用到一些大图片展示的时候,预加载大图是很不错的方法,图片更快的被呈现给用户.不多说了,作为一个前端攻城师都懂的,下面分享我做的测试和得到的结果. 先说需要知道的服务器返回的status code:status-code: 200 - 客户端请求成功status-code: 304 -