av激情亚洲男人的天堂国语,日韩欧美精品一中文字幕,无码av一区二区三区无码,国产又色又爽又刺激的a片,国产又色又爽又刺激的a片

Servlet在session中共享鏈接

問題所在

創(chuàng)新互聯(lián)專注于企業(yè)成都全網(wǎng)營銷推廣、網(wǎng)站重做改版、新干網(wǎng)站定制設(shè)計、自適應(yīng)品牌網(wǎng)站建設(shè)、HTML5建站、商城網(wǎng)站開發(fā)、集團公司官網(wǎng)建設(shè)、成都外貿(mào)網(wǎng)站制作、高端網(wǎng)站制作、響應(yīng)式網(wǎng)頁設(shè)計等建站業(yè)務(wù),價格優(yōu)惠性價比高,為新干等各大城市提供網(wǎng)站開發(fā)制作服務(wù)。

如果要編寫一個購物車,通常需要寫很多個不同功能的Servlet。例如用戶登錄、添加商品、查詢購物車、結(jié)帳等。

在這些 Servlet 中都需要讀寫數(shù)據(jù)庫。如果我們在每個 Servlet 中都進行連接 -> 讀寫 -> 斷開連接的操作,就會消耗大量的服務(wù)器資源,不僅程序響應(yīng)速度減緩,而且會加重服務(wù)器和數(shù)據(jù)庫的負擔。

把希望寄托于HttpSession

如我們所學,Servlet API 提供了一些方法和類來專門處理短期的會話跟蹤。網(wǎng)站的每個用戶都和 Javax.Servlet.http.HttpSession 對象有關(guān),Servlet使用這個對象來記錄和檢索每個用戶的信息。

幸運的是,我們可以在會話對象中存儲任意的 Java 對象。存儲的方法大家都已經(jīng)很熟悉,就是使用 setAttribute()方法。代表數(shù)據(jù)庫連接的Connection也不例外。

這就為我們讓不同的Servlet在session中共享鏈接帶來的希望。

安全問題

那么,僅僅像下面這樣做就可以了么?

1、在Servlet1中,顯示Servlet在session中設(shè)置一個屬性:
session.setAttribute("connection", connection);

2、在Servlet2中,取出這個屬性:
Connection connection = (Connection) session.getAttribute ("connection");

理論上,沒有問題。在 Servlet1 中產(chǎn)生的 Connection 對象,到了 Servlet2 中可以繼續(xù)使用。

但是如果 Servlet2 不小心改變了 connection 的引用,例如 connection = null; 那么,當它再次把這個connection放入session的屬性當中,其它的 Servlet 就會得到一個指向 null 的 connection!

解決之道

把 connection 直接在 session 中傳來傳去,看來不怎么安全。

解決思路是,我們找一個專門的人來保管這個 connection,在得到請求的時候,由這個人把 connection 的引用返回給調(diào)用者。這樣,即使調(diào)用者不小心把它得到的那份 connection 搞壞了,保管著手里也總還有一個備份。

相應(yīng)的,在 session 的屬性中,我們不再保存 connection 本身,而是把這個保管者存進去。因為他能隨時給我們一個可用的 connection。

這個類的具體寫法是:

 
 
 
  1. public class ConnectionHolder {  
  2. public ConnectionHolder(Connection con) {  
  3. // 保存連接  
  4.  
  5. this.con = con;  
  6. try {  
  7. // 禁用自動提交,以隔離不同session之間的操作。  
  8.  
  9. con.setAutoCommit(false);  
  10. }  
  11. catch(SQLException e) {  
  12. // 錯誤處理代碼  
  13.  
  14. }  
  15. }  
  16. public Connection getConnection() {  
  17. // 通過這個getter方法獲取連接  
  18.  
  19. return con;  
  20. }  
  21. private Connection con = null; // 設(shè)置為私有變量,這很重要,以確保變量安全。  
  22.  

使用方法

每個 Servlet 在希望取得數(shù)據(jù)庫連接的時候,先看看Servlet在session中是否有這個“保管者”(即上面的ConnectionHolder)。

如果有的話,直接調(diào)用它的get方法,取得數(shù)據(jù)庫連接。

如果沒有的話,說明這個session還沒有連接過數(shù)據(jù)庫,那么當前類就立刻創(chuàng)建一個數(shù)據(jù)庫連接,并把這個連接交給保管者,然后再把保管者放入 session 中,以便后續(xù)的 Servlet 使用。

下面是一個實例:

 
 
 
  1. protected void doGet(HttpServletRequest req, HttpServletResponse res)  
  2. throws ServletException, IOException {  
  3. // 同步代碼取得數(shù)據(jù)庫連接  
  4. synchronized (session) {  
  5. // 看看這個持有者是否已經(jīng)在 session 中了  
  6. ConnectionHolder holder = (ConnectionHolder) session.getAttribute  
  7. ("servletapp.connection");  
  8. // 如果不在,就創(chuàng)建一個數(shù)據(jù)庫連接,并把它交給持有者。  
  9. if (holder == null) {  
  10. try {  
  11. holder = new ConnectionHolder(DriverManager.getConnection(  
  12. "Connection URL"));  
  13. session.setAttribute("servletapp.connection", holder);  
  14. }  
  15. catch (SQLException sqle) {  
  16. // 錯誤處理代碼  
  17. }  
  18. }  
  19. // 從容器取得實際連接  
  20. conn = holder.getConnection();  
  21. }  
  22. .... // 別忘了commit  

這段代碼看起來有那么幾行。但實際上,在每個session中,只有第一次執(zhí)行的Servlet需要進行數(shù)據(jù)庫連接操作,此后的Servlet只會執(zhí)行第4、6、20這三行。

誰來負責斷開連接?

當 Servlet 們不必再為創(chuàng)建數(shù)據(jù)庫連接費心的時候,也就沒有人愿意管關(guān)閉連接這檔子事了。事實上,更重要的是,他們沒法管。因為這個連接是放在 session 中的,而沒有誰能準確的預(yù)測,一個 session 會何時終止。

好在有一種叫做“監(jiān)聽器”(Listener)的東西可以專門管這件事。Listener有很多方法,其中的兩個方法是:
◆public void valueBound(HttpSessionBingEvent event);
◆public void valueUnbound(HttpSessionBingEvent event);

這兩個方法可以在一個 session 被創(chuàng)建/失效的時候分別自動執(zhí)行。我們就把關(guān)閉連接的代碼放在第二個方法中,這樣,當一個 session 失效的時候,數(shù)據(jù)庫連接就會自動關(guān)閉。

要想讓一個類成為Listener,只需讓它實現(xiàn) HttpSessionBindingListener 接口。我們的 connection 是由 ConnectionHolder 這個類來保管的,因此最方便的辦法就是把它注冊成一個監(jiān)聽器。

具體方法是:

 
 
 
  1. public void valueUnbound(HttpSessionBindingEvent event) {  
  2. // 當從Session刪除或當Session結(jié)束時,關(guān)閉數(shù)據(jù)連接。  
  3. try {  
  4. if (con != null) {  
  5. con.rollback(); // 放棄所有未提交的數(shù)據(jù)  
  6. con.close();  
  7. }  
  8. }  
  9. catch (SQLException e) {  
  10. // 錯誤處理代碼  
  11. }  
  12. }  
  13.  
  14. ConnectionHolder:  
  15.  
  16. import javax.servlet.http.HttpSessionBindingListener;  
  17. import javax.servlet.http.HttpSessionBindingEvent;  
  18. import java.sql.Connection;  
  19. import java.sql.SQLException;  
  20. public class ConnectionHolder implements HttpSessionBindingListener {  
  21. public ConnectionHolder(Connection con) {  
  22. // 保存連接  
  23. this.con = con;  
  24. try {  
  25. con.setAutoCommit(false);  
  26. }  
  27. catch(SQLException e) {  
  28. // 錯誤處理代碼  
  29. }  
  30. }  
  31. public Connection getConnection() {  
  32. return con;  
  33. }  
  34. public void valueBound(HttpSessionBindingEvent event) {  
  35. // 當增加Session時,什么也不做  
  36. }  
  37. public void valueUnbound(HttpSessionBindingEvent event) {  
  38. // 當從Session刪除或當Session結(jié)束時,關(guān)閉數(shù)據(jù)連接。  
  39. try {  
  40. if (con != null) {  
  41. con.rollback(); // 放棄所有未發(fā)送數(shù)據(jù)  
  42. con.close();  
  43. }  
  44. }  
  45. catch (SQLException e) {  
  46. // 錯誤處理代碼  
  47. }  
  48. }  
  49. private Connection con = null;  

文章標題:Servlet在session中共享鏈接
網(wǎng)址分享:http://uogjgqi.cn/article/djoecpo.html
掃二維碼與項目經(jīng)理溝通

我們在微信上24小時期待你的聲音

解答本文疑問/技術(shù)咨詢/運營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流