標籤:todo user catch data rac 而且 use 位置 積累
要想瞭解ServletContextListener,先看看web.xml中的<listener>配置。
一)web.xml中的內容載入順序:
首先能夠肯定的是,載入順序與它們在 web.xml 檔案裡的先後順序無關。
即不會由於 filter 寫在 listener 的前面而會先載入 filter。終於得出的結論是:listener -> filter -> servlet
同一時候還存在著這樣一種配置節:context-param,它用於向 ServletContext 提供索引值對,即應用程式上下文資訊。我們的 listener, filter 等在初始化時會用到這些上下文中的資訊,那麼 context-param 配置節是不是應該寫在 listener 配置節前呢?實際上 context-param 配置節可寫在任何位置,因此真正的載入順序為:context-param -> listener -> filter -> servlet
對於某類配置節而言,與它們出現的順序是有關的。
以 filter 為例。web.xml 中當然能夠定義多個 filter,與 filter 相關的一個配置節是 filter-mapping,這裡一定要注意,對於擁有同樣 filter-name 的 filter 和 filter-mapping 配置節而言。filter-mapping 必須出如今 filter 之後。否則當解析到 filter-mapping 時。它所相應的 filter-name 還沒有定義。web 容器啟動時初始化每一個 filter 時,是依照 filter 配置節出現的順序來初始化的,當請求資源匹配多個 filter-mapping 時,filter 攔截資源是依照 filter-mapping 配置節出現的順序來依次調用 doFilter() 方法的。
servlet 同 filter 類似 ,此處不再贅述。
由此,能夠看出,web.xml 的載入順序是:context-param -> listener -> filter -> servlet ,而同個類型之間的實際程式調用的時候的順序是依據相應的 mapping 的順序進行調用的。
二)ServletContextListener 是什麼:從上面載入順序分享一下,ServletContextListener 就是一個監聽器。
ServletContext 被 Servlet 程式用來與 Web 容器通訊。
比如寫日誌,轉寄請求。每個 Web 應用程式含有一個Context,被Web應用內的各個程式共用。
由於Context能夠用來儲存資源而且共用,所以我所知道的 ServletContext 的最大應用是Web緩衝----把不常常更改的內容讀入記憶體。所以server響應請求的時候就不須要進行慢速的磁碟I/O了。
ServletContextListener 是 ServletContext 的監聽者,假設 ServletContext 發生變化,如server啟動時 ServletContext 被建立,server關閉時 ServletContext 將要被銷毀。
在JSP檔案裡。application 是 ServletContext 的執行個體,由JSP容器預設建立。Servlet 中調用 getServletContext()方法得到 ServletContext 的執行個體。
三)ServletContextListener 可以做些什麼:一切你想做的,就是一個監聽器可以做的事。
1.設計緩衝:
思路:
緩衝的思路大概是:
1)server啟動時,ServletContextListener 的 contextInitialized()方法被調用,所以在裡面建立好緩衝。能夠從檔案裡或者從資料庫中讀取取緩衝內容產生類,用 ervletContext.setAttribute()方法將緩衝類儲存在 ServletContext 的執行個體中。
2)程式使用 ServletContext.getAttribute()讀取緩衝。
假設是 JSP。使用a pplication.getAttribute()。假設是 Servlet。使用 getServletContext().getAttribute()。
假設緩衝發生變化(如訪問計數),你能夠同一時候更改緩衝和檔案/資料庫。
或者你等 變化積累到一定程式再儲存。也能夠在下一步儲存。
3)server將要關閉時,ServletContextListener 的 contextDestroyed()方法被調用,所以在裡面儲存緩衝的更改。將更改後的緩衝儲存迴文件或者資料庫,更新原來的內容。
import User; //my own classimport DatabaseManager; // my own classimport javax.servlet.ServletContext;import javax.servlet.ServletContextListener;public class MyContextListenerimplements ServletContextListener {private ServletContext context = null;public void contextInitialized(ServletContextEvent event) {context = event.getServletContext();User user = DatabaseManager.getUserById(1);context.setAttribute("user1", user);}public void contextDestroyed(ServletContextEvent event) {User user = (User)context.getAttribute("user1");DatabaseManager.updateUserData(user);this.context = null;}}
2)推斷一個設定檔的編碼格式:
public class InitProperties implements ServletContextListener {private static final Logger logger = Logger.getLogger(InitProperties.class);@Overridepublic void contextDestroyed(ServletContextEvent arg0) {// TODO Auto-generated method stub}/** * 該監聽器僅僅用於初始化時監聽設定檔是否是utf-8編碼 且僅僅在初始化時運行一次 對興許的各種請求無影響 * **/@Overridepublic void contextInitialized(ServletContextEvent arg0) {//載入檔案的編碼格式 查看是否是utf-8類型的try {String fileUrl = PropertiesHander.class.getResource("/evoucher.conf").toString();fileUrl = fileUrl.replace("file:","");File file = new File(fileUrl);InputStreamios = new java.io.FileInputStream(file);byte[] b = new byte[3];try {ios.read(b);ios.close();} catch (IOException e) {logger.error("檢測編碼載入時關閉流出現載入異常");} //預設編碼是 23 23 23 的 相同能夠載入這樣的預設的編碼if (b[0] == 35 && b[1] == 35 && b[2] == 35) {logger.info(file.getName() + ":編碼為預設編碼"); } //utf-8編碼的首字母是 ef bb bf else if (b[0] == -17 && b[1] == -69 && b[2] == -65) {logger.info(file.getName() + ":編碼為UTF-8"); }else { try{ // logger.error(file.getName() + "檔案編碼格式不是UTF-8編碼。請又一次確定編碼格式!"); throw new EVoucherException(file.getName() + "檔案編碼格式不是UTF-8編碼,請又一次確定編碼格式!"); } catch(EVoucherException e){ // logger.error(e); EVoucherException.getEVException(null, e, logger); System.exit(0); } }} catch (FileNotFoundException e) {logger.error("檢測編碼時載入檔案出現異常");}}}
四)布署 ServletContextListener
<listener><listener-class>MyServletContextListener</listener-class></listener>
<!-- 自己主動監聽設定檔是否是utf-8編碼 --><listener> <listener-class>assp.evoucher.common.util.InitProperties</listener-class> </listener>
web.xml中的ServletContextListener