Servlet 細節 2
1 Servlet 配置詳解
① 由於客戶端在瀏覽器只能通過URL訪問web服務器的資源,所以Servlet程序若想被外界訪問,必須把Servlet 程序映射到一個URL 地址上,這個工作在項目web.xml 完成。
② web.xml 的 <servlet>元素用於註冊Servlet,它主要包含2個元素:<servlet-name>與<servlet-class>,分別用於註冊Servlet 名稱和設置Servlet 完整類名。
1 <servlet> 2 <!-- 註冊Servlet -->3 <servlet-name>FirstServlet</servlet-name> 4 <!-- 類的全路徑 --> 5 <servlet-class>com.latiny.servlet.FirstServlet</servlet-class> 6 </servlet>
③ <servlet-mapping> 元素用於映射一個已經註冊的Servlet對外的訪問路徑,它包含2個子元素:<servlet-name>與<url-pattern>,分別用於指定Servlet 註冊名對應的對外訪問路徑。
1 <servlet-mapping> 2 <!--Servlet的註冊名 --> 3 <servlet-name>FirstServlet</servlet-name> 4 <!--Servlet對外的訪問路徑 --> 5 <url-pattern>/FirstServlet</url-pattern> 6 </servlet-mapping>
④ 一個註冊的Servlet可以映射為多個URL,且每個URL都可以被外部訪問
⑤ 對Servlet映射時,可以使用通配符,有兩種格式
第一種格式 *.擴展名,例如*.do,*.html
第二中格式 以 / 開頭,同時以 /* 結尾 例如 /* 或者 /news/*
第三如果一個URL被映射成多種格式,匹配標準如下:
- 誰的匹配度高,誰先被選擇
- *.do 優先級最低
案例:
① 如果在上面的<servlet-mapping> 元素裏,FirstServlet 被映射成 *.html,那麽在瀏覽器輸入任何以html 結尾的地址都可以訪問到該 Servlet
http://localhost:8080/TestWeb/abc.html,其中abc 可以換成任意字符都可以訪問到該Servlet。
② 如果在上面的<servlet-mapping> 元素裏,FirstServlet 被映射成 /*,那麽在瀏覽器輸入任何字符或者不輸字符都可以訪問到FirstServlet,如下面的地址都可以訪問到:
http://localhost:8080/ServletProject/
http://localhost:8080/ServletProject/a
http://localhost:8080/ServletProject/.html
2 Servlet 單例問題
當Servlet第一次被訪問後,就被加載到內存,以後該實例對各個請求服務,Servlet在使用中是單例的,因為Servlet是單例,因此會出現線程安全問題。比如:售票系統,不加同步機制,則會出現問題。
① 解決方案:
如果一個變量或者一段代碼,可能會有多個用戶共享,則應該在訪問時加同步機制:
1 synchronized(對象) 2 { 3 4 }
如果一個變量不需要共享,則直接在doPost或doGet定義。
3 Servlet中的<servlet-on-startup> 配置
當我們啟動網站的時候,可能會要求初始化一些數據,比如創建臨時表、完成一些網站要求定時完成的任務如:定時寫日誌,定時備份數據庫,定時發送郵件等。
解決方案:可以通過<load-on-startup>配合線程解決
① 通過配置<load-on-startup> 可以指定某個Servlet 自動啟動
② 創建一個簡單的線程:
1 public class SendEmail extends Thread 2 { 3 public void run() 4 { 5 int i=0; 6 try 7 { 8 while(true) 9 { 10 //每休息10秒,就去掃描sendmail表,看看哪份email應該發出 11 Thread.sleep(60*1000); 12 System.out.println("發出第"+(++i)+"郵件"); 13 } 14 } 15 catch(Exception e) 16 { 17 18 } 19 } 20 21 }
③ 創建一個簡單的Servlet:FirstServlet,然後在該Servlet裏創建SendEmail 線程並啟動
1 public class FirstServlet extends HttpServlet { 2 3 public void init() throws ServletException { 4 //完成一些初始化任務 5 System.out.println("FirstServlet is called"); 6 SendEmail email = new SendEmail(); 7 email.start(); 8 9 } 10 11 public void destroy() { 12 super.destroy(); 13 14 } 15 .......
④ 在項目的web.xml配置該Servlet,隨著網站啟動時一起啟動
1 <servlet> 2 <servlet-name>FirstServlet</servlet-name> 3 <servlet-class>com.latiny.servlet.FirstServlet</servlet-class> 4 <load-on-startup>1</load-on-startup> 5 </servlet>
⑤ 部署該項目,然後啟動Tomcat,啟動之後我們可以在後臺看到,每隔10秒就會輸出一條信息
1 一月 27, 2018 4:39:51 下午 org.apache.coyote.AbstractProtocol start 2 信息: Starting ProtocolHandler ["ajp-apr-8009"] 3 一月 27, 2018 4:39:51 下午 org.apache.catalina.startup.Catalina start 4 信息: Server startup in 5818 ms 5 發出第1郵件 6 發出第2郵件 7 發出第3郵件 8 發出第4郵件 9 發出第5郵件 10 發出第6郵件 11 發出第7郵件
以上只是簡單的模擬了<load-on-startup> 配置Servlet 在項目啟動時跟著一起啟動的案例。
3 SerlvetConfig 對象
ServletConfig 對象主要用於讀取Servlet的配置信息,要在項目中使用該對象來工作,需要做如下操作:
① 在web.xml 中給對應的Servlet 配置ServletConfig 信息,註意這個配置信息只能供該Servlet 訪問,其他Servlet無法訪問
1 <servlet> 2 <servlet-name>FirstServlet</servlet-name> 3 <servlet-class>com.latiny.servlet.FirstServlet</servlet-class> 4 5 6 <!-- Servlet 配置信息,此處配置信息只能被該Servlet讀取 --> 7 <init-param> 8 <param-name>encoding</param-name> 9 <param-value>utf-8</param-value> 10 </init-param> 11 12 <init-param> 13 <param-name>name</param-name> 14 <param-value>latiny</param-value> 15 </init-param> 16 17 <init-param> 18 <param-name>gender</param-name> 19 <param-value>male</param-value> 20 </init-param> 21 22 </servlet>
② 獲取使用
1 String encoding = this.getServletConfig().getInitParameter("encoding"); 2 String name = this.getServletConfig().getInitParameter("name"); 3 String gender = this.getServletConfig().getInitParameter("gender");
這種配置方式只能被某個Serlvet獨立使用,如果希望所有Servlet都能讀取到某個配置參數,則需要配置參數<context-param>
1 <context-param> 2 <param-name>contextName</param-name> 3 <param-value>Hello context config</param-value> 4 </context-param>
該項目任何Servlet 都可以通過以下代碼獲取<context-param> 中的配置
1 String contextName = this.getServletContext().getInitParameter("contextName");
4 修改Servlet的配置模板
MyEclipse提供的Servlet 模板有時候不一定適合項目的開發,為了方便我們可以按照實際需要修改模板
① 找到MyEclipse安裝目錄下的 \Common\plugins文件夾:
D:\Program Files\AppData\Local\MyEclipse\Common\plugins
② 然後找到com.genuitec.eclipse.wizards_9.0.0.me201211011550.jar這個jar文件
③ 用壓縮工具打開,註意是打開不是解壓這個jar包
④ 打開com.genuitec.eclipse.wizards_9.0.0.me201211011550.jar這個jar文件後,可以看到裏面有一個templates文件夾,進入templates文件夾,可以看到裏面有一個Servlet.java文件,然後打開按照自己的需求修改即可
Servlet 細節 2