日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java 会话共享_java – servlet如何工作?实例化,会话,共享变量和多线程

發布時間:2023/12/10 编程问答 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java 会话共享_java – servlet如何工作?实例化,会话,共享变量和多线程 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

假設,我有一個擁有大量servlet的Web服務器.對于在這些servlet之間傳遞的信息,我正在設置會話和實例變量.

現在,如果有2個或更多用戶向此服務器發送請求,那么會話變量會發生什么?它們對所有用戶都是通用的,或者對于每個用戶而言都是不同的.如果它們不同,那么服務器如何區分不同的用戶?

還有一個類似的問題,如果有n個用戶訪問特定的servlet,那么這個servlet只在第一個用戶第一次訪問它時實例化,或者是否為所有用戶分別實例化?換句話說,實例變量會發生什么?

解決方法:

ServletContext中

當servlet容器(如Apache Tomcat)啟動時,它將部署并加載其所有Web應用程序.加載Web應用程序時,servlet容器會創建一次ServletContext并將其保留在服務器的內存中.解析web應用程序的web.xml和所有包含的web-fragment.xml文件,并且每個< servlet>,< filter>和< listener>找到(或者分別用@WebServlet,@ WebFilter和@WebListener注釋的每個類)實例化一次并保存在服務器的內存中.對于每個實例化的過濾器,使用新的FilterConfig調用其init()方法.

當Servlet具有< servlet>< load-on-startup>或@WebServlet(loadOnStartup)值大于0,然后在啟動期間使用新的ServletConfig調用其init()方法.這些servlet按照該值指定的相同順序進行初始化(1為1,2,為2等) .如果為多個servlet指定了相同的值,則每個servlet的加載順序與web.xml,web-fragment.xml或@WebServlet類加載中的順序相同.如果沒有“load-on-startup”值,只要HTTP請求第一次訪問該servlet,就會調用init()方法.

當servlet容器關閉時,它會卸載所有Web應用程序,調用所有初始化的servlet和過濾器的destroy()方法,并且所有ServletContext,Servlet,Filter和Listener實例都會被刪除.最后將調用ServletContextListener#contextDestroyed().

HttpServletRequest和HttpServletResponse

servlet容器連接到Web服務器,該服務器偵聽特定端口號上的HTTP請求(端口8080通常在開發期間使用,端口80在生產中使用).當客戶端(例如,具有Web瀏覽器的用戶或programmatically using URLConnection)發送HTTP請求時,servlet容器會創建新的HttpServletRequest和HttpServletResponse對象,并將它們傳遞給鏈中任何已定義的Filter,最終傳遞給Servlet實例.

在filters的情況下,調用doFilter()方法.當servlet容器的代碼調用chain.doFilter(request,response)時,請求和響應將繼續執行下一個過濾器,或者如果沒有剩余過濾器則命中servlet.

在servlets的情況下,調用service()方法.默認情況下,此方法根據request.getMethod()確定要調用哪個doXxx()方法.如果servlet中沒有確定的方法,則在響應中返回HTTP 405錯誤.

請求對象提供對HTTP請求的所有信息的訪問,例如URL,標題,查詢字符串和正文.響應對象提供了以您希望的方式控制和發送HTTP響應的功能,例如,允許您設置標頭和正文(通常使用JSP文件中生成的HTML內容).提交并完成HTTP響應后,請求和響應對象都將被回收并可供重用.

HttpSession中

當客戶端第一次訪問webapp和/或第一次通過request.getSession()獲取HttpSession時,servlet容器會創建一個新的HttpSession對象,生成一個長且唯一的ID(可以通過session獲取) .getId()),并將其存儲在服務器的內存中. servlet容器還在HTTP響應的Set-Cookie標頭中設置Cookie,其中JSESSIONID作為其名稱,唯一會話ID作為其值.

根據HTTP cookie specification(任何體面的Web瀏覽器和Web服務器必須遵守的合同),只要cookie有效,客戶端(Web瀏覽器)就需要在Cookie標頭中的后續請求中發回此cookie(即唯一ID必須引用未到期的會話,域和路徑是正確的).使用瀏覽器的內置HTTP流量監視器,您可以驗證cookie是否有效(在Chrome / Firefox 23 / IE9中按F12,然后選中Net / Network選項卡). servlet容器將檢查每個傳入HTTP請求的Cookie頭是否存在名為JSESSIONID的cookie,并使用其值(會話ID)從服務器的內存中獲取關聯的HttpSession.

HttpSession保持活動狀態,直到它空閑(即未在請求中使用)超過< session-timeout>(web.xml中的設置)中指定的超時值.超時值默認為30分鐘.因此,當客戶端訪問Web應用程序的時間超過指定的時間時,servlet容器會破壞會話.即使指定了cookie,每個后續請求也將無法再訪問同一個會話; servlet容器將創建一個新會話.

在客戶端,只要瀏覽器實例正在運行,會話cookie就會保持活動狀態.因此,如果客戶端關閉瀏覽器實例(所有選項卡/窗口),則會話在客戶端被刪除.在新的瀏覽器實例中,與會話關聯的cookie將不存在,因此將不再發送.這會導致創建一個全新的HttpSession,并使用一個全新的會話cookie.

簡而言之

>只要Web應用程序存在,ServletContext就會存在.它在所有會話中的所有請求之間共享.

>只要客戶端使用相同的瀏覽器實例與Web應用程序交互,HttpSession就會存在,并且會話在服務器端沒有超時.它在同一會話中的所有請求之間共享.

> HttpServletRequest和HttpServletResponse從servlet接收來自客戶端的HTTP請求開始,直到完整響應(網頁)到達.它不在別處分享.

>只要Web應用程序存在,所有Servlet,過濾器和偵聽器實例都會生效.它們在所有會話中的所有請求之間共享.

>只要有問題的對象存在,ServletContext,HttpServletRequest和HttpSession中定義的任何屬性都將存在.對象本身表示bean管理框架中的“范圍”,例如JSF,CDI,Spring等.這些框架將其作用域bean存儲為其最接近匹配范圍的屬性.

線程安全

也就是說,您主要關心的可能是線程安全.您現在應該知道servlet和過濾器在所有請求之間共享.這是關于Java的好東西,它是多線程的,不同的線程(讀取:HTTP請求)可以使用相同的實例.否則,為每個請求重新創建,init()和destroy()它們會非常昂貴.

您還應該意識到,您永遠不應將任何請求或會話范圍數據分配為servlet或過濾器的實例變量.它將在其他會話中的所有其他請求之間共享.這不是線程安全的!以下示例說明了這一點:

public class ExampleServlet extends HttpServlet {

private Object thisIsNOTThreadSafe;

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

Object thisIsThreadSafe;

thisIsNOTThreadSafe = request.getParameter("foo"); // BAD!! Shared among all requests!

thisIsThreadSafe = request.getParameter("foo"); // OK, this is thread safe.

}

}

也可以看看:

總結

以上是生活随笔為你收集整理的java 会话共享_java – servlet如何工作?实例化,会话,共享变量和多线程的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。