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หรือ@WebServletclassloading ในกรณีที่ไม่มีค่า "การโหลดเมื่อเริ่มต้น" 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.
}
}
ดูสิ่งนี้ด้วย: