如何获取初始化参数

容器在初始化的时候,会为了这个Servlet创建一个唯一的ServletConfig,容器会从DD读出Servlet的初始化参数,并把这个参数交给ServletConfig,然后ServletConfig传递给Servlet的init()方法。

这样做的好处就是当你需要更改某个参数的值时,只要在配置文件中更改即可,如果是在Servlet中硬编码,则需要重新编译。

在DD文件中这样配置

  <servlet>
<servlet-name>name</servlet-name>
<servlet-class>class-name</servlet-class> <init-param>
<param-name>name</param-name>
<param-value>value</param-value>
</init-param>
</servlet>

在Servlet代码中只要这样调用就行:

  out.println(getServletConfig().getInitParameter("name"));

注意:获得此参数的时机:不要在Servlet的构造函数中调用此方法,因为这时候还没有执行init方法,所以没有ServletConfig。

JSP能不能获取到Servlet初始化参数

ServletConfig仅用于Servlet的初始化配置,所以如果想让应用的其他部分也能使用这部分初始化配置信息,则需要别的方法。

解决办法:

因为在前面提到过,ServletContext是整个web应用的参数,所以无论Servlet还是JSP都能访问到,所以在这里配置,应该是极好的。

 <Servlet>
............
</servlet>
   //注意不能嵌套在上面的Servlet配置里面。
 <context-param>
<param-name>name</param-name>
<param-value>value</para-value>
</context-param>

调用方法:

 out.println(getServletContext().getInitParameter("canshu"));

如果应用是分布式应用,则在每一个JVM中都会有一个ServletContext.

那么问题来了,上面的访问方法时Servlet访问ServletContext的方法,在JSP中有怎么样呢?

在JSP中有一些所谓的“隐式对象”,其中就包括ServletContext.关于JSP的详细介绍请参见本博客。

应用初始化参数如果不只是String类型呢,比如DataSource?

此时需要一个监听器(listener),即监听一个上下文初始化事件,这样就能得到一个上下文初始化参数,并在应用为客户提供服务之前运行一些代码。

比如获取数据库连接,则需要一个ServletContextListener。它可以建立一个单独的类,不是Servlet或者JSP,用来监听ServletContext的创建和撤销。此类实现了javax.servlet.ServletContextListener

关于此例,需要做到:

  • 上下文初始化(应用部署中)得到通知

    从ServletContext得到上下文初始化参数;

    从初始化参数查找名建立一个数据库连接

    把数据库连接存储为一个属性,使得Web应用的各个部分都能访问

  • 上下文撤销时,得到通知

    关闭数据库连接

  • 代码段

   import javax.servlet.*;
   public class MyServletContextListener implements ServletContextListener {
   public void contextInitialized(ServletContextEvent event)    {
//code to initialize the database connection
//and store it as a context attribute
}
   public  void contextDestroyed(ServletContextEvent event) {
//code to close the database connection
}
}

如何建立一个上下文监听者

1.创建一个监听类实现监听接口,并且像上面的代码所示,实现两个方法;

2.要在web.xml部署文件放一个元素

	<listener>
<listener-class>class</listener-class>
</listener>
//这个文件要部署到Servlet外面去

注意:通过getAttribute方法获取一个属性时,一定要注意强制转换,因为此方法返回的是一个Object类型。

除了监听上下文还能监听什么?

事实上,除了监听上下文事件,还可以监听与上下文属性、Servlet请求和属性,以及HTTP会话和会话属性相关的事情。

以下列出了八种监听器以及适用场合

什么是属性

上面提到了属性,到底什么是属性呢?

属性实质就是一个对象,可能设置到或者绑定到ServletContext、HttpServletRequest或者HttpSession对象中的某一个。

简言之,就是一个映射实例对象中的键值对(String-Object)。

属性和参数有什么区别?

类型不同:属性类型包括应用,请求,会话;参数类型包括应用初始化参数,请求参数,Servlet初始化参数。

设置方法不同:属性通过setAttribute(String name, Object value)设置;而参数通过DD设置

返回类型不同:属性返回的是一个对象,参数返回的一个字符串

获取方法:属性通过getAttribute(String name)获取,参数通过getInitParameter(String name)方法获取。

属性的API

上下文、请求和会话都由相应的接口处理,即ServletConfig、ServletRequest和HttpSession。每个接口的API方法完全相同。

	Object getAttribute(String name)

	void setAttribute(String name,Object value)

	void removeAttribute(String name)

	Enumeration getAttributeNames()

需要注意的一点是:上下文作用域不是线程安全的。因为应用中可能有多个Servlet,而每一个Servlet都能访问上下文属性,而请求又是并发的,所以会出现线程安全问题。

如何做到上下文属性线程安全?

可以有一个思路就是:同步。

在每个Servlet的doGet()方法中同步。但是这样做的一个后果就是Servlet再也不能进行并发处理了,一次只能处理一个客户。

而且只能意味着Servlet中一次只能运行一个线程,同一个Servlet中的其他线程访问上下文属性,但是不能阻止另一个不同的servlet的访问

所以一个可行的办法是:对于上下文加锁。

代码实例:

public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException,ServletException {
synchronized(getServletContext()) {
//get the attribute and do something
}
}

如何做到会话属性线程安全?

首先应该弄清楚一个概念,会话属性是线程安全的吗?

答:否。

因为同一个用户很有可能会在同时做出多个请求(可以想象:同一个客户可能打开一个新的浏览器窗口,容器吧来自第二个窗口的请求看作是来自同一个会话)。

代码实例:

public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException,ServletException {
HttpSession session = request.getSession();
synchronized(session) {
//make use of the session and set Attributes
}
}

关于同步的忠告:因为同步要检查、获得和释放锁,所以确实会增加一些额外的开销,但是不论是哪一种形式的锁都有一条标准:一定要在最短的时间完成目标,使持有锁的时间最短。要让同步块尽可能的小。

怎么让Servlet一次只得到一个请求?

首先要了解一个接口:SingleThreadModel(STM).

这个接口没有任何方法,如果一个Servlet实现了这个接口,就可以保证不会在该Servlet的服务方法中并发执行两个线程。通过同步实现对Servlet单个实例的访问,或者通过维护一个Servlet实例池并把每个新请求分配到一个空闲的Servlet,而Servlet容器可以做到这样一点。

记住:只有请求属性和局部变量是线程安全的。

关于RequestDispatcher

只有两个方法:forward()和include()

1.从ServletRequest得到RequestDispatcher

	RequestDispatcher view = request.getRequestDispatcher("result.jsp");
//注意:上面的参数如果不是以 /开头,则是相对路径,反之,则是绝对路径。

2.从ServletContext得到RequestDispatcher

	RequestDispatcher view = getServletContext().getRequestDispatcher("/result.jsp");
//注意:此处路径必须以/开头

然后,在RequestDispatcher上调用forward()方法

	view.forward(request,response);

Servlet 浅谈(二)的更多相关文章

  1. Servlet 浅谈(一)

    Servlet 的生命周期 类加载.实例化,init方法,service方法,destroy方法.关于这点,后面会有详细介绍. 什么是容器? 因为Servlet没有main方法,所以它受控于另一个Ja ...

  2. 浅谈二维RMQ

    针对一些二维区间最值问题,用一维RMQ来解决显然是不够的.所以,要改进算法.鉴于网上没有PASCAL版的RMQ标程与解析,所以小可在这里简单的讲一下. 核心思想和一维的一样,只是在计算区间时略有不同. ...

  3. Servlet 浅谈(三)

    关于Session 关于http协议后面会有一系列文章专门介绍.这里就大概了解一下:首先需要知道一点:HTTP是无状态的. 什么是无状态呢? 客户与服务器建立连接.发出请求.得到响应.关闭连接.整个流 ...

  4. 源码浅谈(二):java中的 Integer.parseInt(String str)方法

    这个方法是将字符串转换为整型 一.parseInt方法 ,可以看到默认又调用了parseInt(s,10) ,  第二个参数为基数,默认10 ,当然也可以自己设置  public static int ...

  5. salesforce lightning零基础学习(九) Aura Js 浅谈二: Event篇

    上一篇介绍了Aura Framework中 Component类的部分方法,本篇将要介绍Event常用的方法. 1. setParam (String key , Object value):设置事件 ...

  6. 转: 浅谈C/C++中的指针和数组(二)

    转自:http://www.cnblogs.com/dolphin0520/archive/2011/11/09/2242419.html 浅谈C/C++中的指针和数组(二) 前面已经讨论了指针和数组 ...

  7. 浅谈前后端分离与实践 之 nodejs 中间层服务(二)

    一.背景 书接上文,浅谈前后端分离与实践(一) 我们用mock服务器搭建起来了自己的前端数据模拟服务,前后端开发过程中只需定义好接口规范,便可以相互进行各自的开发任务.联调的时候,按照之前定义的开发规 ...

  8. 浅谈Tomcat和Servlet

    本文浅谈下对Tomcat和Servlet总体的理解,初学时有用过一段时间,但当时疲于应对如何xml配置和使用,对他们的理解就像是一个黑匣子.现在回顾一下帮助自己加深网络的理解.开始还是先推荐我看的文章 ...

  9. 浅谈Kotlin(二):基本类型、基本语法、代码风格

    浅谈Kotlin(一):简介及Android Studio中配置 浅谈Kotlin(二):基本类型.基本语法.代码风格 浅谈Kotlin(三):类 浅谈Kotlin(四):控制流 通过上面的文章,在A ...

随机推荐

  1. 自学HTML的几个例子

    此处不赘述HTML中不同标签的用法仅仅给出自己学习时写的一些自娱自乐的例子,具体标签用法请参考W3C(http://www.w3school.com.cn/),毕竟这个才是最靠谱的,请不要相信任何二道 ...

  2. windows 7 旗舰版 切换 中英文 界面

    http://jingyan.baidu.com/article/f7ff0bfc4963612e26bb131e.html 如果遇到:想下载英语语言包,但是出现代码80070643,windowsu ...

  3. HDU 5145 - NPY and girls

    题意: cases T(1≤T≤10) (0<n,m≤30000) (0<ai≤30000)    n个数ai 表示n个女孩所在教室 m次询问 [L,R](1 <= L <= ...

  4. JavaScript实现div宽、高自动缓慢拉伸

    最近打算实现一个带有滤镜效果的地自动拉伸图片.发现使用css3浏览器兼容性得需要特别关注.这里我使用js实现了一个div边框自动拉伸和缩小.源码如下: <!DOCTYPE html>< ...

  5. 从汇编看c++中指向成员变量的指针(一)

    在c++中,指向类成员变量的指针存储的并不是该成员变量所在内存的地址,而仅仅是该成员变量在该类对象中相对于对象首地址的偏移量.因此,它必须绑定到某一个对象或者对象指针上面,这里的对象和对象指针,就相当 ...

  6. 关于mysql的安装

    上个学期学了数据库后,曾多次试图安装数据库,但由于电脑的种种的原因或者是安装的问题,始终没能安装成功,今天终于succeed. 一.下载 首先从www.mysql.com网站上下载mysql,我下载的 ...

  7. 日志管理-NLog日志框架简写用法

    本文转载:http://www.blogjava.net/qiyadeng/archive/2013/02/27/395799.html 在.net中也有非常多的日志工具,今天介绍下NLog.NLog ...

  8. AngularJS入门基础PPT(附下载链接)

    学习了Angularjs有段时间,自己写了一个PPT,个人认为总结的非常全面,对于入门基础够了. 大致模块有:Angularjs简单介绍,Angularjs特性,hello world,Control ...

  9. webStorm 列编辑

    webStorm可以像Sublime一样使用列编辑,只是区别在于webStorm只可以编辑连续列表. 按住alt键鼠标选择一列,然后输入文字就会编辑多行,这个功能很赞,比较实用

  10. Android studio Debug效率提升

    Android studio Debug效率提升,可以在控制台打印log的同时而不暂停程序的运行,尤其是当遇到复杂交互的时候,比如滑动,拖动,这时候程序暂停执行是特别恶心的.其实你可以更新打印信息而不 ...