前面咱們已經學過了Servlet的生命週期了,咱們根據Servlet的生命週期畫出Servlet的調用圖加深理解php
同一個Servlet能夠被映射到多個URL上。java
<servlet>
<servlet-name>Demo1</servlet-name>
<servlet-class>zhongfucheng.web.Demo1</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Demo1</servlet-name>
<url-pattern>/Demo1</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Demo1</servlet-name>
<url-pattern>/ouzicheng</url-pattern>
</servlet-mapping>
複製代碼
不管我訪問的是http://localhost:8080/Demo1仍是http://localhost:8080/ouzicheng。我訪問的都是Demo1。web
通配符有兩種格式:數據庫
匹配全部apache
匹配擴展名爲.jsp的編程
若是*.擴展名和正斜槓(/)開頭並以「/*」結尾兩種通配符同時出現,匹配的是哪個呢?瀏覽器
*.
擴展名的優先級最低Servlet映射的URL可使用通配符和Servlet能夠被映射到多個URL上的做用:安全
<servlet>
<servlet-name>Demo1</servlet-name>
<servlet-class>zhongfucheng.web.Demo1</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Demo1</servlet-name>
<url-pattern>*.jsp</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Demo1</servlet-name>
<url-pattern>*.net</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Demo1</servlet-name>
<url-pattern>*.asp</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Demo1</servlet-name>
<url-pattern>*.php</url-pattern>
</servlet-mapping>
複製代碼
瀏覽器屢次對Servlet的請求,通常狀況下,服務器只建立一個Servlet對象,也就是說,Servlet對象一旦建立了,就會駐留在內存中,爲後續的請求作服務,直到服務器關閉。服務器
對於每次訪問請求,Servlet引擎都會建立一個新的HttpServletRequest請求對象和一個新的HttpServletResponse響應對象,而後將這兩個對象做爲參數傳遞給它調用的Servlet的service()方法,service方法再根據請求方式分別調用doXXX方法。微信
當多個用戶訪問Servlet的時候,服務器會爲每一個用戶建立一個線程。當多個用戶併發訪問Servlet共享資源的時候就會出現線程安全問題。
原則:
若是在元素中配置了一個元素,那麼WEB應用程序在啓動時,就會裝載並建立Servlet的實例對象、以及調用Servlet實例對象的init()方法。
做用:
當你啓動Tomcat,你在網址上輸入http://localhost:8080。爲何會出現Tomcat小貓的頁面?
這是由缺省Servlet爲你服務的!
<servlet>
<servlet-name>default</servlet-name>
<servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>0</param-value>
</init-param>
<init-param>
<param-name>listings</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
複製代碼
<servlet>
<servlet-name>Demo1</servlet-name>
<servlet-class>zhongfucheng.web.Demo1</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Demo1</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
複製代碼
經過此對象能夠讀取web.xml中配置的初始化參數。
如今問題來了,爲何咱們要把參數信息放到web.xml文件中呢?咱們能夠直接在程序中均可以定義參數信息,搞到web.xml文件中又有什麼好處呢?
好處就是:可以讓你的程序更加靈活【更換需求,更改配置文件web.xml便可,程序代碼不用改】
<servlet>
<servlet-name>Demo1</servlet-name>
<servlet-class>zhongfucheng.web.Demo1</servlet-class>
<init-param>
<param-name>name</param-name>
<param-value>zhongfucheng</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>Demo1</servlet-name>
<url-pattern>/Demo1</url-pattern>
</servlet-mapping>
複製代碼
當Tomcat啓動的時候,就會建立一個ServletContext對象。它表明着當前web站點
ServletContext對象能夠被稱之爲域對象
到這裏可能有一個疑問,域對象是什麼呢?其實域對象能夠簡單理解成一個容器【相似於Map集合】
實現Servlet之間通信就要用到ServletContext的setAttribute(String name,Object obj)方法, 第一個參數是關鍵字,第二個參數是你要存儲的對象
//獲取到ServletContext對象
ServletContext servletContext = this.getServletContext();
String value = "zhongfucheng";
//MyName做爲關鍵字,value做爲值存進 域對象【類型於Map集合】
servletContext.setAttribute("MyName", value);
複製代碼
//獲取ServletContext對象
ServletContext servletContext = this.getServletContext();
//經過關鍵字獲取存儲在域對象的值
String value = (String) servletContext.getAttribute("MyName");
System.out.println(value);
複製代碼
若是我想要讓全部的Servlet都可以獲取到鏈接數據庫的信息,不可能在web.xml文件中每一個Servlet中都配置一下,這樣代碼量太大了!而且會顯得很是囉嗦冗餘。
<context-param>
<param-name>name</param-name>
<param-value>zhongfucheng</param-value>
</context-param>
複製代碼
//獲取到ServletContext對象
ServletContext servletContext = this.getServletContext();
//經過名稱獲取值
String value = servletContext.getInitParameter("name");
System.out.println(value);
複製代碼
//獲取到ServletContext對象
ServletContext servletContext = this.getServletContext();
//經過名稱獲取值
String value = servletContext.getInitParameter("name");
System.out.println(value);
複製代碼
第一種方式:
FileInputStream fileInputStream = new FileInputStream("1.png");
System.out.println(fileInputStream);
複製代碼
FileInputStream fileInputStream = new FileInputStream("D:\\zhongfucheng\\web\\WEB-INF\\classes\\zhongfucheng\\web\\1.png");
System.out.println(fileInputStream);
複製代碼
//獲取到ServletContext對象
ServletContext servletContext = this.getServletContext();
//調用ServletContext方法獲取到讀取文件的流
InputStream inputStream = servletContext.getResourceAsStream("/WEB-INF/classes/zhongfucheng/web/1.png");
複製代碼
第二種方式:
//獲取到ServletContext對象
ServletContext servletContext = this.getServletContext();
//調用ServletContext方法獲取到讀取文件的流
InputStream inputStream = servletContext.getResourceAsStream("2.png");
複製代碼
第三種方式:
經過類裝載器讀取資源文件。
//獲取到類裝載器
ClassLoader classLoader = Servlet111.class.getClassLoader();
//經過類裝載器獲取到讀取文件流
InputStream inputStream = classLoader.getResourceAsStream("3.png");
複製代碼
//獲取到類裝載器
ClassLoader classLoader = Servlet111.class.getClassLoader();
//經過類裝載器獲取到讀取文件流
InputStream inputStream = classLoader.getResourceAsStream("/zhongfucheng/web/1.png");
複製代碼
原則:若是文件太大,就不能用類裝載器的方式去讀取,會致使內存溢出
若是文章有錯的地方歡迎指正,你們互相交流。習慣在微信看技術文章的同窗,能夠關注微信公衆號:Java3y