ServletContext
เมื่อ servlet container (เช่นApache Tomcat ) เริ่มทำงานมันจะปรับใช้และโหลดเว็บแอปพลิเคชันทั้งหมด เมื่อโหลดแอปพลิเคชันเว็บ servlet container จะสร้างServletContext
หนึ่งครั้งและเก็บไว้ในหน่วยความจำของเซิร์ฟเวอร์ เว็บแอปฯweb.xml
และทั้งหมดของรวมweb-fragment.xml
ไฟล์จะแยกกันและแต่ละคน<servlet>
, <filter>
และ<listener>
พบ (หรือแต่ละชั้นข้อเขียนด้วย@WebServlet
, @WebFilter
และ@WebListener
ตามลำดับ) ถูกสร้างครั้งเดียวและเก็บไว้ในหน่วยความจำของเซิร์ฟเวอร์ได้เป็นอย่างดี สำหรับแต่ละตัวกรอง instantiated มันวิธีการถูกเรียกด้วยใหม่init()
FilterConfig
เมื่อServlet
มี<servlet><load-on-startup>
หรือ@WebServlet(loadOnStartup)
มากขึ้นกว่าค่า0
แล้วของวิธีการที่จะเรียกยังระหว่างการเริ่มต้นกับใหม่init()
ServletConfig
เซิร์ฟเล็ตเหล่านั้นถูกเตรียมข้อมูลเบื้องต้นตามลำดับที่ระบุโดยค่านั้น ( 1
คือที่ 1 2
คือที่ 2 และอื่น ๆ ) หากค่าเดียวกันที่ระบุไว้มากกว่าหนึ่งเซิร์ฟเล็ตแล้วแต่ละ Servlets ผู้ที่มีการโหลดในลำดับเดียวกันตามที่ปรากฏในweb.xml
, web-fragment.xml
หรือ@WebServlet
classloading ในกรณีที่ไม่มีค่า "การโหลดเมื่อเริ่มต้น" init()
วิธีการจะถูกเรียกใช้เมื่อใดก็ตามที่คำขอ HTTP เข้าชมเซิร์ฟเล็ตนั้นเป็นครั้งแรก
เมื่อเซิร์ฟเล็ตคอนเทนเนอร์เสร็จสิ้นด้วยขั้นตอนการกำหนดค่าเริ่มต้นทั้งหมดที่อธิบายไว้ข้างต้นแล้วServletContextListener#contextInitialized()
จะถูกเรียกใช้
เมื่อปิดภาชนะ servlet ลงก็ unloads การใช้งานเว็บที่ทุกคนเรียกdestroy()
วิธีการ Servlets ทั้งหมดเริ่มต้นและตัวกรองและทั้งหมดServletContext
, Servlet
, Filter
และListener
อินสแตนซ์กำลังอยู่ในถังขยะ ในที่สุดServletContextListener#contextDestroyed()
ก็จะถูกเรียก
HttpServletRequest และ HttpServletResponse
servlet container นั้นเชื่อมต่อกับเว็บเซิร์ฟเวอร์ที่รับฟังคำร้องขอ HTTP ในหมายเลขพอร์ตที่แน่นอน (โดยปกติจะใช้พอร์ต 8080 ระหว่างการพัฒนาและพอร์ต 80 ในการผลิต) เมื่อไคลเอนต์ (เช่นผู้ใช้ที่มีเว็บเบราว์เซอร์หรือใช้โปรแกรมURLConnection
) ส่งคำร้องขอ HTTP คอนเทนเนอร์ servlet จะสร้างสิ่งใหม่HttpServletRequest
และHttpServletResponse
วัตถุและส่งผ่านสิ่งที่กำหนดไว้Filter
ในห่วงโซ่และในที่สุดServlet
อินสแตนซ์
ในกรณีของฟิลเตอร์ที่doFilter()
วิธีการที่จะเรียก เมื่อโค้ดของคอนเทนเนอร์ servlet chain.doFilter(request, response)
การร้องขอและการตอบสนองดำเนินการต่อไปยังตัวกรองถัดไปหรือกด servlet ถ้าไม่มีตัวกรองที่เหลืออยู่
ในกรณีของServletsที่service()
วิธีการที่จะเรียก โดยค่าเริ่มต้นวิธีการนี้จะกำหนดว่าหนึ่งในวิธีการที่จะเรียกตามออกของdoXxx()
request.getMethod()
หากเมธอดที่กำหนดไม่อยู่ในเซิร์ฟเล็ตดังนั้นข้อผิดพลาด HTTP 405 จะถูกส่งคืนในการตอบกลับ
วัตถุคำขอให้การเข้าถึงข้อมูลทั้งหมดเกี่ยวกับการร้องขอ HTTP เช่น URL ส่วนหัวสตริงการสืบค้นและเนื้อหา อ็อบเจ็กต์การตอบกลับจัดเตรียมความสามารถในการควบคุมและส่งการตอบกลับ HTTP ตามที่คุณต้องการเช่นอนุญาตให้คุณตั้งค่าส่วนหัวและเนื้อหา (โดยปกติจะมีเนื้อหา HTML ที่สร้างขึ้นจากไฟล์ JSP) เมื่อการตอบสนอง HTTP ถูกคอมมิตและเสร็จสิ้นทั้งคำร้องขอและออบเจ็กต์การตอบสนองจะถูกนำมารีไซเคิลและทำให้พร้อมใช้งานสำหรับการใช้ซ้ำ
HttpSession
เมื่อลูกค้าเยี่ยมชมเว็บแอปเป็นครั้งแรกและ / หรือHttpSession
ได้รับเป็นครั้งแรกผ่านทางrequest.getSession()
ภาชนะ servlet จะสร้างHttpSession
วัตถุใหม่สร้างรหัสยาวและไม่ซ้ำกัน (ซึ่งคุณสามารถรับได้session.getId()
) และเก็บไว้ในเซิร์ฟเวอร์ หน่วยความจำ เซิร์ฟเล็ตคอนเทนเนอร์ยังตั้งค่าCookie
ในSet-Cookie
ส่วนหัวของการตอบกลับ HTTP ด้วยJSESSIONID
เป็นชื่อและ ID เซสชันที่ไม่ซ้ำกันเป็นค่า
ตามข้อกำหนดของคุกกี้ HTTP (สัญญาเว็บเบราเซอร์และเว็บเซิร์ฟเวอร์ใด ๆ ที่ดีจะต้องปฏิบัติตาม) ลูกค้า (เว็บเบราว์เซอร์) จะต้องส่งคุกกี้นี้กลับมาในคำขอที่ตามมาในCookie
ส่วนหัวตราบเท่าที่คุกกี้นั้นถูกต้อง ( เช่น ID ที่ไม่ซ้ำต้องอ้างอิงถึงเซสชันที่ยังไม่หมดอายุและโดเมนและเส้นทางถูกต้อง) เมื่อใช้การตรวจสอบปริมาณข้อมูล HTTP ในเบราว์เซอร์ของคุณคุณสามารถตรวจสอบว่าคุกกี้นั้นถูกต้อง (กด F12 ใน Chrome / Firefox 23+ / IE9 + และตรวจสอบแท็บNet / Network ) ภาชนะ servlet จะตรวจสอบCookie
ส่วนหัวของคำขอ HTTP ที่เข้ามาทุกครั้งสำหรับการมีคุกกี้ที่มีชื่อJSESSIONID
และใช้ค่าของมัน (ID เซสชั่น) เพื่อให้ได้รับการเชื่อมโยงHttpSession
จากหน่วยความจำของเซิร์ฟเวอร์
HttpSession
คงมีชีวิตอยู่จนกว่าจะได้รับการว่าง (คือไม่ได้ใช้ในการร้องขอ) มานานกว่าค่าหมดเวลาที่ระบุไว้ในการตั้งค่าใน<session-timeout>
web.xml
ค่าการหมดเวลาเริ่มต้นที่ 30 นาที ดังนั้นเมื่อไคลเอ็นต์ไม่ได้เยี่ยมชมเว็บแอพพลิเคชั่นนานกว่าเวลาที่กำหนด servlet container จะลบเซสชัน ทุกคำขอที่ตามมาแม้จะมีการระบุคุกกี้จะไม่สามารถเข้าถึงเซสชันเดียวกันได้อีกต่อไป เซิร์ฟเล็ตคอนเทนเนอร์จะสร้างเซสชันใหม่
ในฝั่งไคลเอ็นต์คุกกี้เซสชันจะมีชีวิตอยู่ตราบใดที่อินสแตนซ์เบราว์เซอร์กำลังทำงาน ดังนั้นหากลูกค้าปิดอินสแตนซ์ของเบราว์เซอร์ (แท็บ / หน้าต่างทั้งหมด) ดังนั้นเซสชันจะถูกทิ้งในด้านของลูกค้า ในอินสแตนซ์เบราว์เซอร์ใหม่คุกกี้ที่เกี่ยวข้องกับเซสชันจะไม่มีอยู่ดังนั้นจะไม่ถูกส่งอีกต่อไป สิ่งนี้ทำให้เกิดการHttpSession
สร้างใหม่ทั้งหมดโดยมีการใช้คุกกี้เซสชันใหม่ทั้งหมด
โดยสังเขป
- มี
ServletContext
ชีวิตอยู่ตราบใดที่เว็บแอปมีชีวิตอยู่ มันถูกใช้ร่วมกันระหว่างทุกคำขอในทุกการประชุม
HttpSession
ชีวิตได้นานเท่าที่ลูกค้าจะโต้ตอบกับแอปเว็บด้วยเบราว์เซอร์เช่นเดียวกันและช่วงที่ยังไม่ได้หมดเวลาที่ฝั่งเซิร์ฟเวอร์ มันถูกใช้ร่วมกันระหว่างคำขอทั้งหมดในเซสชั่นเดียวกัน
HttpServletRequest
และHttpServletResponse
สดจากเวลาเซิร์ฟเล็ตที่ได้รับการร้องขอ HTTP จากลูกค้าจนการตอบสนองสมบูรณ์ (หน้าเว็บ) ได้มาถึง มันเป็นเรื่องที่ไม่ได้ใช้ร่วมกันที่อื่น
- ทั้งหมด
Servlet
, Filter
และListener
กรณีมีชีวิตอยู่ตราบเท่าที่ชีวิตของ app เว็บ พวกเขาจะใช้ร่วมกันระหว่างทุกคำขอในทุกการประชุม
- ใด ๆ
attribute
ที่กำหนดไว้ในServletContext
, HttpServletRequest
และHttpSession
จะมีชีวิตอยู่ได้นานเท่าที่วัตถุในชีวิตของคำถาม วัตถุนั้นแสดงถึง "ขอบเขต" ในเฟรมเวิร์กการจัดการถั่วเช่น JSF, CDI, Spring เป็นต้นเฟรมเวิร์กเหล่านั้นเก็บถั่วที่กำหนดขอบเขตไว้เป็นattribute
ขอบเขตการจับคู่ที่ใกล้เคียงที่สุด
ความปลอดภัยด้าย
ที่กล่าวว่าความกังวลหลักของคุณอาจจะเป็นความปลอดภัยหัวข้อ ตอนนี้คุณควรรู้ว่า servlets และตัวกรองถูกแชร์ในคำขอทั้งหมด นั่นเป็นสิ่งที่ดีเกี่ยวกับ Java มันเป็นเธรดหลายเธรดและเธรดที่แตกต่างกัน (อ่าน: คำขอ HTTP) สามารถใช้อินสแตนซ์เดียวกันได้ มันจะมีราคาแพงเกินไปที่จะสร้างใหม่init()
และdestroy()
พวกเขาสำหรับทุกคำขอ
คุณควรตระหนักว่าคุณไม่ควรกำหนดคำขอหรือข้อมูลที่กำหนดขอบเขตใด ๆ เป็นตัวแปรอินสแตนซ์ของเซิร์ฟเล็ตหรือตัวกรอง มันจะถูกใช้ร่วมกันระหว่างคำขออื่น ๆ ทั้งหมดในช่วงอื่น ๆ นั่นไม่ใช่หัวข้อที่ปลอดภัย! ตัวอย่างด้านล่างแสดงสิ่งนี้:
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.
}
}
ดูสิ่งนี้ด้วย: