Servlet细节

1.一个已经注册的Servlet可以被多次映射

  <servlet>
    <servlet-name>MyServlet1</servlet-name>
    <servlet-class>com.hsin.servlet.MyServlet1</servlet-class>
  </servlet>
  <!--第一个映射-->
  <servlet-mapping>
    <servlet-name>MyServlet1</servlet-name>
    <url-pattern>/MyServlet1</url-pattern>
  </servlet-mapping>
  <!--第二个映射-->
  <servlet-mapping>
    <servlet-name>MyServlet1</servlet-name>
    <url-pattern>/MyServlet1Again</url-pattern>
  </servlet-mapping>

2.后缀名是 html 不一定就是 html,可能是假象

<url-pattern>/index.html</url-pattern>

3.当映射一个servlet时候,可以多层 

<url-pattern>/servlet/index.html</url-pattern>

4.使用通配符在servlet映射到URL中

第一种格式: *.扩展名 , 比如 *.do 、 *.ss

<url-pattern>*.do</url-pattern>

第二种格式:以 / 开头,以 /* 结尾 , 比如  /* 、  /news/* 

<url-pattern>/*</url-pattern>
<url-pattern>/news/*</url-pattern>

通配符练习题:

l  Servlet1 映射到 /abc/*

l  Servlet2 映射到 /*

l  Servlet3 映射到 /abc

l  Servlet4 映射到 *.do

问题(面试题):

l  当请求URL为“/abc/a.html”,“/abc/*”和“/*”都匹配,哪个servlet响应

       Servlet引擎将调用Servlet1。

l  当请求URL为“/abc”时,“/abc/*”和“/abc”都匹配,哪个servlet响应

       Servlet引擎将调用Servlet3。

l  当请求URL为“/abc/a.do”时,“/abc/*”和“*.do”都匹配,哪个servlet响应

       Servlet引擎将调用Servlet1

l  当请求URL为“/a.do”时,“/*”和“*.do”都匹配,哪个servlet响应

       Servlet引擎将调用Servlet2。

l  当请求URL为“/xxx/yyy/a.do”时,“/*”和“*.do”都匹配,哪个servlet响应

       Servlet引擎将调用Servlet2。

在匹配的时候,要参考的标准:

(1)  看谁的匹配度高,谁就被选中

(2)  *.do 的优先级最低

5.Servlet单例问题

当Servlet被第一次访问后,就被加载到内存,以后该实例对各个请求服务即在使用中是单例。

因为 Servlet是单例,因此会出现线程安全问题,比如:售票系统. 如果不加同步机制,则会出现问题

(1)如果一个变量需要多个用户共享,则应当在访问该变量的时候,加同步机制

synchronized (对象){

       //同步代码
}

(2)如果一个变量不需要共享,则直接在 doGet() 或者 doPost()定义(局部变量)这样不会存在线程安全问题

6.<load-on-startup>

1)load-on-startup元素标记容器是否在启动的时候就加载这个servlet(实例化并调用其init()方法)。

2)它的值必须是一个整数,表示servlet应该被载入的顺序

3)当值为0或者大于0时,表示容器在应用启动时就加载并初始化这个servlet;

4)当值小于0或者没有指定时,则表示容器在该servlet被选择时才会去加载。

5)正数的值越小,该servlet的优先级越高,应用启动时就越先加载。

6)当值相同时,容器就会自己选择顺序来加载。

所以,<load-on-startup>x</load-on-startup>,中x的取值1,2,3,4,5代表的是优先级,而非启动延迟时间。