1. 程式人生 > >Servlet 細節 2

Servlet 細節 2

str 日誌 lan sta 對象 public lang 找到 ram

  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