国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開(kāi)發(fā)設(shè)計(jì) > 正文

JavaServlet工作原理問(wèn)答

2019-11-14 14:56:27
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

導(dǎo)讀

本文來(lái)自stackoverflow的問(wèn)答,討論了java Servlet的工作機(jī)制,如何進(jìn)行實(shí)例化、共享變量和多線程處理。

問(wèn)題:Servlet是如何工作的?Servlet 如何實(shí)例化、共享變量、并進(jìn)行多線程處理?

假設(shè)我有一個(gè)運(yùn)行了大量 Servlet 的 web 服務(wù)器。通過(guò) Servlet 之間傳輸信息得到 Servlet 上下文,并設(shè)置 session 變量。

現(xiàn)在,如果有兩名或更多使用者向這個(gè)服務(wù)發(fā)送請(qǐng)求,接下來(lái) session 變量會(huì)發(fā)生什么變化?究竟是所有用戶都是用共同的變量?還是不同的用戶使用的變量都不一樣?如果是后者,服務(wù)器如何區(qū)分不同用戶?

另一個(gè)相似的問(wèn)題,如果有 *n* 名用戶訪問(wèn)一個(gè)特定的 Servlet,那么該 Servlet 是僅在第一個(gè)用戶首次訪問(wèn)的時(shí)候?qū)嵗?,還是分別為每個(gè)用戶實(shí)例化?

回答(BalusC):

ServletContext

當(dāng) Servlet 容器(比如 Apache Tomcat)啟動(dòng)后,會(huì)部署和加載所有 web 應(yīng)用。當(dāng)web 應(yīng)用被加載,Servlet 容器會(huì)創(chuàng)建一次 ServletContext,然后將其保存在服務(wù)器的內(nèi)存中。web 應(yīng)用的web.xml 被解析,找到其中所有 servletfilter 和 Listener 或 @WebServlet、@WebFilter和 @WebListener 注解的內(nèi)容,創(chuàng)建一次并保存到服務(wù)器的內(nèi)存中。對(duì)于所有過(guò)濾器會(huì)立即調(diào)用init()。當(dāng) Servlet 容器停止,將卸載所有 web 應(yīng)用,調(diào)用所有初始化的 Servlet 和過(guò)濾器的destroy() 方法,最后回收 ServletContext 和所有 Servlet、Filter 與 Listener 實(shí)例。

當(dāng)問(wèn)題中的 Servlet 配置的 load-on-startup 或者 @WebServlet(loadOnStartup) 設(shè)置了一個(gè)大于 0 的值,則同樣會(huì)在啟動(dòng)的時(shí)候立即調(diào)用 init() 方法。“load-on-startup”中的值表示那些 Servlet 會(huì)以相同順序初始化。如果配置的值相同,會(huì)遵循 web.xml 中指定的順序或 @WebServlet類(lèi)加載的順序。另外,如果不設(shè)置 “load-on-startup” 值,init() 方法只在第一次 HTTP 請(qǐng)求命中問(wèn)題中的 Servlet 時(shí)才被調(diào)用。

HttpServletRequest 與 HttpServletResponse

Servlet 容器附加在一個(gè) web 服務(wù)上,這個(gè) web 服務(wù)會(huì)在某個(gè)端口號(hào)上監(jiān)聽(tīng) HTTP 請(qǐng)求,在開(kāi)發(fā)環(huán)境中這個(gè)端口通常為 8080,生產(chǎn)環(huán)境中通常為 80。當(dāng)客戶端(web 瀏覽器)發(fā)送了一個(gè) HTTP 請(qǐng)求,Servlet 容器會(huì)創(chuàng)建新的 HttpServletRequest 和 HttpServletResponse 對(duì)象,傳遞給已創(chuàng)建好并且請(qǐng)求的 URL 匹配 url-pattern 的 Filter 和 Servlet 實(shí)例中的方法,所有工作都在同一個(gè)線程中處理。

request 對(duì)象可以訪問(wèn)所有該 HTTP 請(qǐng)求中的信息,例如 request header 和 request body。response 對(duì)象為你提供需要的控制和發(fā)送 HTTP 響應(yīng)方法,例如設(shè)置 header 和 body(通常會(huì)帶有 jsp 文件中的 HTML 內(nèi)容)。提交并完成HTTP 響應(yīng)后,將回收 request 和 response 對(duì)象。

HttpSession

當(dāng)用戶第一次訪問(wèn)該 web 應(yīng)用時(shí),會(huì)通過(guò) request.getSession() 第一次獲得 HttpSession。之后 Servlet 容器將會(huì)創(chuàng)建 HttpSession,生成一個(gè)唯一的 ID(可以通過(guò) session.getId() 獲?。┎?chǔ)存在服務(wù)器內(nèi)存中。然后 Servlet 容器在該次 HTTP 響應(yīng)的 Set-Cookie 頭部設(shè)置一個(gè)Cookie,以 JSESSIONID 作為 Cookie 名字,那個(gè)唯一的 session ID 作為 Cookie 的值。

按照 HTTP cookie 規(guī)則(正常 web 瀏覽器和 web 服務(wù)端必須遵循的標(biāo)準(zhǔn)),當(dāng) cookie 有效時(shí),要求客戶端(瀏覽器)在后續(xù)請(qǐng)求的 Cookie 頭中返回這個(gè) cookie。使用瀏覽器內(nèi)置的 HTTP 流量監(jiān)控器,你可以查看它們(在 Chrome、Firefox23+、IE9+ 中按 F12,然后查看 Net/Network 標(biāo)簽)。Servlet 容器將會(huì)確定每個(gè)進(jìn)入的 HTTP 請(qǐng)求的 Cookie 頭中是否存在名為JSESSIONID 的 cookie,然后用它的值(session ID)從服務(wù)端內(nèi)存中找到關(guān)聯(lián)的 HttpSession。

你可以在 web.xml 中設(shè)置 session-timeout ,默認(rèn)值為 30 分鐘。超時(shí)到達(dá)之前 HttpSession 會(huì)一直存活。所以當(dāng)客戶端不再訪問(wèn)該 web 應(yīng)用超過(guò) 30 分鐘后,Servlet 容器就會(huì)回收這個(gè) session。后續(xù)每個(gè)請(qǐng)求,即使指定 cookie 名稱(chēng)也不能再訪問(wèn)到相同的 session。Servlet 容器會(huì)創(chuàng)建一個(gè)新的 Cookie。

另一方面,客戶端上的 session cookie 有一個(gè)默認(rèn)存活時(shí)間,該事件和該瀏覽器實(shí)例運(yùn)行時(shí)間一樣長(zhǎng)。所以,當(dāng)客戶端關(guān)閉該瀏覽器實(shí)例(所有標(biāo)簽和窗口)后,這個(gè) session 就會(huì)被客戶端回收。新瀏覽器實(shí)例不再發(fā)送與該 session 關(guān)聯(lián)的 cookie。一個(gè)新的 request.getSession() 將會(huì)返回新的 HttpSession 并設(shè)置一個(gè)擁有新 session ID 的 cookie。

概述

  • ServletContext 與 web 應(yīng)用存活時(shí)間一樣長(zhǎng)。它被所有 session 中的所有請(qǐng)求共享。
  • 只要客戶端一直與相同瀏覽器實(shí)例的web應(yīng)用交互并且沒(méi)有超時(shí),HttpSession就會(huì)存在。
  • HttpServletRequest 和 HttpServletResponse 的存活時(shí)間為客戶端發(fā)送完成到完整的響應(yīng)(web 頁(yè)面)到達(dá)的這段時(shí)間。不會(huì)被其他地方共享。
  • 所有 ServletFilter 和 Listener 對(duì)象在 web 應(yīng)用運(yùn)行時(shí)都是活躍的。它們被所有 session 中的請(qǐng)求共享。
  • 你設(shè)置在 HttpServletRequest、HttpServletResponse 和 HttpSession 中的所有屬性在問(wèn)題中的對(duì)象存活時(shí)都會(huì)一直保持存活。

線程安全

即便如此,你最關(guān)心的可能是線程安全。你現(xiàn)在應(yīng)該學(xué)習(xí)到 Servlet 和 filter 被所有請(qǐng)求共享。那是 Java 的一個(gè)優(yōu)點(diǎn),使得多個(gè)不同線程(讀取 HTTP 請(qǐng)求)可以使用同一個(gè)實(shí)例。否則為每個(gè)請(qǐng)求重新創(chuàng)建線程的開(kāi)銷(xiāo)實(shí)在過(guò)于昂貴。

但你應(yīng)該也意識(shí)到永遠(yuǎn)不要將任何 request 或 session 域中的數(shù)據(jù)賦值給 servlet 或 filter 的實(shí)例變量。它將會(huì)被所有其他 session 中的所有請(qǐng)求共享。那是非線程安全的!下面的示例對(duì)這種情況進(jìn)行了展示:

1
2
3
4
5
6
7
8
9
10
11
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.
    }
}

 

前兩天在一群里看見(jiàn)有人推薦一個(gè)app叫問(wèn)啊,就可以發(fā)題答題那種的,感覺(jué)就跟uber滴滴打車(chē)似的,一般這種軟件一上來(lái)就砸錢(qián)給紅包啥的,哥之前刷過(guò)uber的單有經(jīng)驗(yàn)!試驗(yàn)了幾次應(yīng)該可以刷,把注冊(cè)紅包和之前領(lǐng)的紅包錢(qián)套現(xiàn),目前我提了五十多,目測(cè)還能刷更多。ps,但是盡量要問(wèn)技術(shù)相關(guān)的問(wèn)題,不然容易被封。

  有技術(shù)的可以自己試,不會(huì)的可以q我:QQ群290551701


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 大化| 棋牌| 虹口区| 宿松县| 九龙坡区| 台前县| 翼城县| 文山县| 锡林浩特市| 北辰区| 唐山市| 日土县| 南川市| 安吉县| 乌拉特前旗| 西丰县| 万荣县| 新津县| 高尔夫| 松溪县| 车致| 龙江县| 本溪| 泉州市| 英吉沙县| 神木县| 玉田县| 河曲县| 江达县| 阜宁县| 泽普县| 饶阳县| 林芝县| 灵璧县| 丰县| 成武县| 谷城县| 墨玉县| 渝中区| 柘荣县| 舒城县|