คำนำ
สำหรับนักพัฒนา Java เราควรคุ้นเคยกับเซสชันในข้อกำหนด J2EE สำหรับนักพัฒนาส่วนใหญ่ที่ใช้ Tomcat เป็นเว็บคอนเทนเนอร์ Tomcat ใช้เซสชันเพื่อทำเครื่องหมายผู้ใช้และจัดการข้อมูลเซสชันอย่างไร
สรุป
การประชุม
Tomcat กำหนดอินเทอร์เฟซที่เกี่ยวข้องกับเซสชันและ HTTPSESSION ระบบการสืบทอดคลาสจะแสดงในรูปที่ 1
รูปที่ 1 ระบบการสืบทอดคลาสเซสชันคลาส
รูปที่ 1 นอกจากนี้ยังแสดงรายการระบบการสืบทอดคลาสของเซสชันและพวกเขาจะถูกแนะนำทีละรายการที่นี่
เซสชัน: ข้อมูลจำเพาะอินเตอร์เฟสพื้นฐานสำหรับเซสชันใน Tomcat
ตารางที่ 1 คำอธิบายอินเตอร์เฟสเซสชัน
วิธี | อธิบาย |
getCreationTime ()/setCreationTime (เวลา: ยาว) | รับและตั้งค่าเวลาการสร้างของเซสชัน |
getId ()/setId (id: string) | รับและตั้งค่า ID ของเซสชัน |
getThisaccessedTime () | รับเวลาเริ่มต้นของคำขอล่าสุด |
getLaScessedTime () | รับเวลาเสร็จสิ้นของคำขอล่าสุด |
getManager ()/setManager (ผู้จัดการ: ผู้จัดการ) | รับและตั้งค่า Session Manager |
getMaxinactiveInterval ()/setMaxinactiveInterval (ช่วงเวลา: int) | รับช่วงเวลาการเข้าถึงสูงสุดระหว่างการตั้งค่าเซสชัน |
getSession () | รับ httpsession |
isvalid ()/setValid (isvalid: บูลีน) | รับและตั้งค่าสถานะที่ถูกต้องของเซสชัน |
การเข้าถึง ()/endaccess () | เริ่มต้นและสิ้นสุดการเข้าถึงเซสชัน |
หมดอายุ() | ตั้งค่าเซสชันหมดอายุ |
HTTPSESSION: ข้อมูลจำเพาะอินเตอร์เฟสสำหรับเซสชันที่จัดทำโดยไคลเอนต์ HTTP และเซิร์ฟเวอร์ HTTP รูปที่ 1 แสดงวิธีการหลักที่กำหนดและตารางที่ 2 แนะนำวิธีการเหล่านี้
ตารางที่ 2 คำอธิบายอินเตอร์เฟส httpsession
วิธี | อธิบาย |
getCreationTime () | รับเวลาสร้างของเซสชั่น |
getId () | รับรหัสเซสชัน |
getLaScessedTime () | รับเวลาเสร็จสิ้นของคำขอล่าสุด |
getServletContext () | รับ servletContext ที่เซสชันปัจจุบันเป็นของ |
getMaxinactiveInterval ()/setMaxinactiveInterval (ช่วงเวลา: int) | รับช่วงเวลาการเข้าถึงสูงสุดระหว่างการตั้งค่าเซสชัน |
getAttribute (ชื่อ: string) /setAttribute (ชื่อ: สตริง, ค่า: วัตถุ) | รับและตั้งค่าคุณสมบัติขอบเขตเซสชัน |
RemoveAttribute (ชื่อ: String) | ล้างคุณสมบัติขอบเขตเซสชัน |
เป็นโมฆะ () | ทำให้เซสชันและยกเลิกวัตถุใด ๆ ที่ผูกไว้กับเซสชันนี้ |
Clustersession: ข้อมูลจำเพาะของเซสชันอินเตอร์เฟสภายใต้การปรับใช้คลัสเตอร์
ตารางที่ 3 คำอธิบายอินเทอร์เฟซ clustersession
วิธี | อธิบาย |
isprimarysession () | มันเป็นเซสชั่นหลักของคลัสเตอร์หรือไม่? |
SetPrimarySession (Boolean Primentsession) | ตั้งค่าเซสชัน Master Cluster |
มาตรฐาน: การใช้งานเซสชัน HTTP มาตรฐานบทความนี้จะใช้การใช้งานนี้เป็นตัวอย่าง
เมื่อปรับใช้คลัสเตอร์ Tomcat สถานะเซสชันของแต่ละโหนดในคลัสเตอร์จะต้องมีการซิงโครไนซ์
ReplicatedSession: ในแต่ละครั้งวัตถุเซสชันทั้งหมดจะถูกซิงโครไนซ์กับโหนดอื่น ๆ ในคลัสเตอร์และโหนดอื่น ๆ จากนั้นอัปเดตวัตถุเซสชันทั้งหมด การใช้งานนี้ค่อนข้างง่ายและสะดวก แต่จะทำให้เกิดการส่งข้อมูลที่ไม่ถูกต้องจำนวนมาก
Deltasession: ซิงโครไนซ์คุณสมบัติที่ปรับเปลี่ยนที่เพิ่มขึ้นในเซสชัน เนื่องจากวิธีนี้เพิ่มขึ้นอย่างมากมันจะลดค่าใช้จ่ายของเครือข่าย I/O อย่างมาก แต่การใช้งานจะซับซ้อนมากขึ้นเนื่องจากเกี่ยวข้องกับการจัดการกระบวนการดำเนินการแอตทริบิวต์เซสชัน
ผู้จัดการเซสชัน
Tomcat กำหนดอินเทอร์เฟซของผู้จัดการภายในสำหรับการกำหนดข้อกำหนดส่วนต่อประสานของผู้จัดการเซสชัน
รูปที่ 2 ระบบการสืบทอดคลาสของ Manager Session
เราจะอธิบายเนื้อหาที่เกี่ยวข้องในรูปที่ 2 ทีละหนึ่งด้านล่าง:
Manager: Tomcat สำหรับข้อกำหนดอินเตอร์เฟสที่กำหนดโดย Session Manager รูปที่ 2 ได้แสดงรายการวิธีหลักที่กำหนดไว้ในอินเทอร์เฟซของผู้จัดการและตารางที่ 4 อธิบายบทบาทของวิธีการเหล่านี้โดยละเอียด
ตารางที่ 4 Manager Interface Description
วิธี | อธิบาย |
getContainer ()/setContainer (คอนเทนเนอร์: คอนเทนเนอร์) | รับหรือตั้งค่าคอนเทนเนอร์ที่เกี่ยวข้องกับตัวจัดการเซสชันโดยทั่วไปจะเป็นคอนเทนเนอร์บริบท |
getDistributable ()/setDistributable (กระจายได้: บูลีน) | รับหรือตั้งค่าว่าผู้จัดการเซสชันรองรับการกระจาย |
getMaxinactiveInterval ()/setMaxinactiveInterval (ช่วงเวลา: int) | รับหรือตั้งค่าช่วงเวลาที่ไม่ได้ใช้งานสูงสุดสำหรับเซสชันที่สร้างโดย Session Manager |
getSessionIdLength ()/setSessionIdLength (idlength: int) | รับหรือตั้งค่าความยาวของรหัสเซสชันที่สร้างโดย Session Manager |
getSessionCounter ()/setSessionCounter (SessionCounter: Long) | รับหรือตั้งค่าจำนวนเซสชันทั้งหมดที่สร้างโดย Manager เซสชัน |
getMaxactive ()/setMaxactive (maxactive: int) | รับหรือตั้งค่าจำนวนสูงสุดของเซสชันที่เปิดใช้งานในปัจจุบัน |
GetactiveSessions () | เปิดใช้งานเซสชันทั้งหมดในปัจจุบัน |
getExpiredSessions ()/setExpiredSessions (ExpiredSessions: Long) | รับหรือตั้งค่าจำนวนเซสชันที่หมดอายุในปัจจุบัน |
getRejectedSessions ()/setRejectedSessions (DENCHEDSESSIONS: INT) | รับหรือตั้งค่าจำนวนเซสชันที่ถูกปฏิเสธว่าจะถูกสร้างขึ้น |
getSessionMaxalivetime ()/setSessionMaxAliveTime (SessionMaxalivetime: int) | รับหรือตั้งค่าระยะเวลากิจกรรมสูงสุดในเซสชันที่หมดอายุ |
getSessionaveragealivetime ()/setsessionaveragealivetime (sessionaveragealivetime: int) | รับหรือตั้งค่าระยะเวลากิจกรรมเฉลี่ยสำหรับเซสชันที่หมดอายุ |
เพิ่ม (เซสชัน: เซสชัน)/ลบ (เซสชัน: เซสชัน) | เพิ่มหรือลบเซสชันที่ใช้งานไปยังตัวจัดการเซสชัน |
การเปลี่ยนแปลง (เซสชัน: เซสชัน) | ตั้งค่ารหัสเซสชันแบบสุ่มที่สร้างขึ้นใหม่สำหรับเซสชัน |
CreateSession (SessionId: String) | สร้างเซสชันใหม่ตามการกำหนดค่าแอตทริบิวต์เริ่มต้นของตัวจัดการเซสชัน |
findsession (id: string) | ส่งคืนเซสชันด้วยเครื่องหมายที่ไม่ซ้ำกันของพารามิเตอร์ SessionID |
foundsessions () | ส่งคืนกิจกรรมทั้งหมดที่จัดการโดยผู้จัดการเซสชัน |
โหลด ()/ยกเลิกการโหลด () | โหลดเซสชันจากกลไกการคงอยู่หรือการเขียนเซสชันไปยังกลไกการคงอยู่ |
พื้นหลัง process () | อินเทอร์เฟซคอนเทนเนอร์ถูกกำหนดให้เป็นงานที่เกี่ยวข้องกับการประมวลผลคอนเทนเนอร์เฉพาะในพื้นหลัง |
ManagerBase : ห่อหุ้มคลาสนามธรรมที่ใช้โดยทั่วไปโดยอินเทอร์เฟซของผู้จัดการ ผู้จัดการเซสชันทั้งหมดได้รับการสืบทอดจาก ManagerBase
ClusterManager : เพิ่มอินเทอร์เฟซบางอย่างภายใต้การปรับใช้คลัสเตอร์ตามอินเตอร์เฟสของผู้จัดการ
PresentententManagerBase: ให้การใช้งานพื้นฐานของการคงอยู่ของเซสชัน
PresentententManager: สืบทอดมาจาก StervantentManagerBase สามารถใช้งานได้โดยการกำหนดค่าองค์ประกอบ <สโตร์> ใน Server.xml StensistentManager สามารถสำรองข้อมูลเซสชันในหน่วยความจำไปยังไฟล์หรือฐานข้อมูล เมื่อวัตถุเซสชันได้รับการสำรองข้อมูลวัตถุเซสชันจะถูกคัดลอกไปยังหน่วยความจำ (ไฟล์หรือฐานข้อมูล) ในขณะที่วัตถุต้นฉบับยังคงอยู่ในหน่วยความจำ ดังนั้นแม้ว่าเซิร์ฟเวอร์จะลดลงวัตถุเซสชันที่ใช้งานยังคงสามารถเรียกคืนได้จากหน่วยความจำ หากวัตถุเซสชันที่ใช้งานเกินขีด จำกัด บนหรือวัตถุเซสชันไม่ได้ใช้งานนานเกินไปเซสชันจะถูกเปลี่ยนเป็นหน่วยความจำเพื่อบันทึกพื้นที่หน่วยความจำ
StandardManager: ไม่จำเป็นต้องกำหนดค่าองค์ประกอบ <store> . เมื่อ Tomcat รีสตาร์ทหรือโหลดแอปพลิเคชัน Tomcat จะกู้คืนเซสชันในไฟล์เป็นหน่วยความจำ หากเซิร์ฟเวอร์สิ้นสุดลงทันทีเซสชันทั้งหมดจะหายไปเนื่องจาก StandardManager ไม่มีโอกาสที่จะใช้การประมวลผลบันทึก
ClusterManagerBase: ให้การใช้งานการจัดการคลัสเตอร์สำหรับเซสชัน
Deltamanager: สืบทอดมาจาก ClusterManagerbase ตัวจัดการเซสชันนี้เป็นผู้จัดการเริ่มต้นของ Tomcat ภายใต้การปรับใช้คลัสเตอร์
BackupManager: ไม่ได้สืบทอด ClusterManagerBase แต่ใช้อินเตอร์เฟส ClusterManager โดยตรง มันเป็นตัวจัดการเซสชันเสริมสำหรับ Tomcat ภายใต้การปรับใช้คลัสเตอร์ โหนดทั้งหมดในคลัสเตอร์สามารถเข้าถึงโหนดสำรองนี้เพื่อให้ได้เอฟเฟกต์การสำรองข้อมูลของเซสชันในคลัสเตอร์
เพื่อความเรียบง่ายบทความนี้ใช้ StandardManager เป็นตัวอย่างในการอธิบายการจัดการเซสชัน StandardManager เป็นส่วนประกอบของเด็กของ StandardContext ที่ใช้ในการจัดการการสร้างและบำรุงรักษาทุกเซสชันของบริบทปัจจุบัน หากคุณควรอ่านหรือคุ้นเคยกับเนื้อหาของบทความ "การวิเคราะห์ซอร์สโค้ด Tomcat - การจัดการวงจรชีวิต" คุณจะรู้ว่าเมื่อมีการเปิดตัว StandardContext อย่างเป็นทางการนั่นคือวิธี startInternal ของ StandardContext (ดูรายการ 1) เรียกว่า StandardContext จะยังคงเริ่มต้น StandardManager
รายการรหัส 1
@Override ป้องกันการซิงโครไนซ์ startInternal () พ่น LifecycleException {// รหัสละเว้นที่ไม่เกี่ยวข้องกับการจัดการเซสชัน // ได้รับ clustered manager manager contextManager = null; && distribute) {ลอง {contextManager = getCluster (). CreateManager (getName ()); StandardManager ();}} // กำหนดค่าตัวจัดการเริ่มต้นหากไม่มีการระบุถ้า (ContextManager! = NULL) {SetManager (ContextManager); แจ้งให้คลัสเตอร์ทราบว่ามีบริบทที่แจกจ่าย // และมีผู้จัดการ GetCluster (). RegisterManager (ผู้จัดการ); if ((manager! = null) && (manager instanceof lifecycle)) {(Lifecycle) getManager ()). start (); .error ("ตัวจัดการข้อผิดพลาดเริ่มต้น ()", e);
จากรายการ 1 คุณจะเห็นว่าวิธี startInternal ของ StandardContext เกี่ยวข้องกับการจัดการเซสชันดังนี้:
สร้าง StandardManager;
หาก Tomcat รวม Apache สำหรับการปรับใช้แบบกระจาย StandardManager ปัจจุบันจะลงทะเบียนในคลัสเตอร์
เริ่ม StandardManager;
วิธีการเริ่มต้นของ StandardManager ใช้ในการเริ่มต้น StandardManager และการใช้งานจะแสดงในรายการ 2 ของรหัส
รหัสรายการ 2
@Override สาธารณะที่ซิงโครไนซ์สุดท้ายเริ่มต้น () พ่น LifecycleException {// ละเว้นรหัสสำหรับการตรวจสอบสถานะถ้า (state.equals (lifecyclestate.new)) {init (); state.equals (Lifecyclestate.stopped)) {InvalidTransition (Lifecycle.Before_start_event); } if (state.equals (lifecyclestate.failed) || state.equals (LifeCyclestate.must_stop)) {stop ()}} {// ไม่จำเป็น การทำสิ่งที่พวกเขาควรจะเป็น
จากรายการ 2 เราจะเห็นว่าขั้นตอนในการเริ่มต้น StandardManager มีดังนี้:
เรียกวิธีการเริ่มต้นเพื่อเริ่มต้น StandardManager;
โทรหาวิธี startInternal เพื่อเริ่ม StandardManager;
การเริ่มต้นของ StandardManager
หลังจากการวิเคราะห์ข้างต้นเรารู้ว่าขั้นตอนแรกในการเริ่มต้น StandardManager คือการเรียกวิธีการเริ่มต้นของ Lifecyclebase คลาสแม่ เพื่อดูแลเกี่ยวกับ initinternal ของ StandardManager StandardManager เองไม่ได้ใช้วิธีการเริ่มต้น แต่ Managerbase คลาสแม่ของ StandardManager ใช้วิธีนี้ดูรายการ 3 สำหรับการใช้งาน
รายการรหัส 3
@Override Void INTINTERNAL () โยน LifeCycleException {super.initinternal ();
การอ่านรายการรหัส 3 เราสรุปขั้นตอนการดำเนินการของวิธีการเริ่มต้นของ ManagerBase:
ลงทะเบียนคอนเทนเนอร์เอง, StandardManager, ถึง JMX (ดูบทความ "การวิเคราะห์ซอร์สโค้ด Tomcat - การจัดการวงจรชีวิต" สำหรับการใช้วิธีการเริ่มต้นของ Lifecyclembeanbase);
รับ Tomcat ปัจจุบันจาก Parent Container StandardContext และตั้งค่าเป็นคุณสมบัติบูลีนของ ManagerBase Distributable;
โทรหาวิธี GetRandombytes เพื่อรับอาร์เรย์ไบต์แบบสุ่มจากไฟล์หมายเลขสุ่ม /dev /urandom
หมายเหตุ: อาร์เรย์ไบต์แบบสุ่มที่สร้างขึ้นโดยการเรียกใช้วิธี Getrandombytes ที่นี่จะไม่ถูกใช้
ลองอ่านการใช้งานรหัสของวิธี GetRandombytes โดยละเอียดดูรายการ 4 ของรหัส
รายการรหัส 4
เป็นโมฆะที่ได้รับการป้องกัน getRandombytes (ไบต์ไบต์ []) {// สร้างอาร์เรย์ไบต์ที่มีตัวระบุเซสชันถ้า (devrandomsource! = null && randomis == null) {set randomfile (devrandomsource); int len = randomis.red (ไบต์); ถ้า (len == bytes.length) {return; Catch (Expection Ex) {// ละทิ้ง} devrandomsource = null; ) .NextBytes (ไบต์);
SetRandomFile ในรายการ 4
วิธีการ (ดูรายการ 5 สำหรับรหัส) ใช้เพื่อรับอาร์เรย์ไบต์หมายเลขสุ่มจากไฟล์หมายเลขสุ่ม /dev /urandom
รายการรหัส 5
โมฆะสาธารณะ setRandomFile (สตริง s) {// เป็นแฮ็คคุณสามารถใช้ไฟล์คงที่ - และสร้างรหัสเซสชันเดียวกัน (ดีสำหรับการดีบักแปลก ๆ ) ถ้า (globals.is_se curity_enabled) {randomis = accessController.doprivileged (ใหม่ Privilegedsetrandomfile (S))} else {ลอง {devrandomsource = s; readlong (); หาก (log.isdebugenabled ()) log.debug ("การเปิด" + devrandomsource); ) {ลอง {randomis.close ();
เมธอด setRandomFile ในรายการ 4 (ดูรายการ 6) สร้างอินสแตนซ์ของ Java.security.Securerandom ผ่านการสะท้อนและใช้อินสแตนซ์นี้เพื่อสร้างอาร์เรย์ของไบต์สุ่ม
รหัสรายการ 6
การสุ่ม public getRandom () {ถ้า (this.random == null) {// คำนวณตัวสร้างตัวเลขสุ่มใหม่เมล็ดพันธุ์ยาว = System.currentTimeMillis (); ); สำหรับ (int i = 0; i <entropy.length; // การสร้างและเมล็ดพันธุ์เครื่องกำเนิดไฟฟ้าแบบสุ่มใหม่ <?> clazz = class.forname (สุ่มคลาส); e) {// กลับไปที่ Log.error (sm.getString ("managerbase.random", แบบสุ่ม), e); (เมล็ด)); ) "" + (T2-T1));
จากการวิเคราะห์ข้างต้นการเริ่มต้นของ StandardManager ส่วนใหญ่จะดำเนินการวิธีการเริ่มต้นของ ManagerBase
เริ่มต้นของ StandardManager
การเรียกใช้วิธี startInternal ของ StandardManager ใช้เพื่อเริ่มต้น StandardManager ดูรายการ 7
รหัสรายการ 7
@Override ป้องกันการซิงโครไนซ์ startInternal () โยน LifecycleException {// การเริ่มต้นการเริ่มต้นของเครื่องกำเนิดตัวเลขสุ่มถ้า (log.isdebugenable d ()) log.debug ("การเริ่มต้นการเริ่มต้นแบบสุ่ม"); isdebugenabled ()) log.debug ("การเริ่มต้นแบบสุ่มหมายเลขเสร็จสิ้น"); managerload "), t);} setState (LifeCyclestate.Starting);}
จากรายการ 7 เราจะเห็นว่าขั้นตอนในการเริ่มต้น StandardManager มีดังนี้:
ขั้นตอนที่ 1: เรียกเมธอด generatesessionId (ดูรายการ 8) เพื่อสร้าง ID เซสชันใหม่
รหัสรายการ 8
สตริงที่ซิงโครไนซ์ได้รับการป้องกัน () {ไบต์สุ่ม [] = ไบต์ใหม่ [16]; ทำ {int resultlenbytes = 0; ; สุ่ม [j] & 0x0f); หาก (b1 <10) บัฟเฟอร์. ((char) ('0' + b1)); ถ้า (B2 <10) บัฟเฟอร์ ((((char) ('0' + b2); jvmroute! ::::::::::::::::::::::: กระทาน ::::::::::::
ขั้นตอนที่ 2 โหลดข้อมูลเซสชันถาวร เหตุใดเซสชันจึงจำเป็นต้องคงอยู่? เนื่องจากเซสชั่นทั้งหมดได้รับการดูแลรักษาใน StandardManager เซิร์ฟเวอร์รีสตาร์ทหรือการหยุดทำงานทำให้ข้อมูลเซสชันเหล่านี้หายไปหรือไม่ถูกต้อง ลองมาดูการใช้วิธีการโหลดของ StandardManager ดูรายการรหัส 9 รายการ
รหัสรายการ 9
Public Void Load () พ่น classnotfoundexception, ioexception {ถ้า (Securityutil.ispackageProtectionEnabled ()) {ลอง {accessController.doprien ข้อยกเว้นของ ClassnotFoundException) {Throw (classnotfoundexception) ข้อยกเว้น; ;
หากจำเป็นต้องเปิดกลไกการรักษาความปลอดภัยและเปิดโหมดการป้องกันแพ็คเกจเซสชันที่คงอยู่จะถูกโหลดโดยการสร้าง privilegedDoload ซึ่งจะถูกนำไปใช้ดังแสดงในรายการ 10 ของรหัส
รายการ 10
Private Class PrivilegedDoLoad ใช้ PrivilegedExceptionAction <Void> {PrivilegedDoLoad () {// noop} โมฆะสาธารณะเรียกใช้ () โยนข้อยกเว้น {do load ();
จากรายการ 10 เราจะเห็นได้ว่าวิธีการที่รับผิดชอบในการโหลดจริงคือ doLoad ดังนั้นเราเพียงแค่ต้องดูการใช้งานของ DoLoad ดูรายการ 11 ของรหัส
รายการ 11
void doLoad () พ่น classnotfoundexception, ioexception {if (log.isdebugenabled ()) log.debug ("เริ่มต้น: การโหลดเซสชันคงที่"); ไปยังชื่อพา ธ ที่ระบุหากไฟล์ใด ๆ ไฟล์ = file (); FileInputStream FIS = NULL; คอนเทนเนอร์! การสร้างสตรีมอินพุตวัตถุที่กำหนดเองสำหรับคลาสโหลดเดอร์ "); ois = ใหม่ customobjectInputStream (bis, classloader);} else {ถ้า (log.isdebugenabled ()) log.debug (" การสร้างสตรีมอินพุต OB ject มาตรฐาน "); ois = New ObjectInputStream (bis); .getString ("StandardManager.loading .Ioe", e), e); null) {ลอง {bis readobject (); int n = count.intvalue (); {Standardsession Session = GetNewsession (); ) {// ถ้าเซสชันไม่ถูกต้อง // เซสชันหมดอายุเพื่อป้องกันการรั่วไหลของหน่วยความจำ GetString ("StandardManager.loading.cnfe", e), e); .getString ("StandardManager.loading. ioe", e), e); ois.close ();} catch (ioexception f) {// ถูกละเว้น} // ลบไฟล์ที่เก็บข้อมูลแบบถาวรถ้า (file.exists ()) file.delete (); การดีบัก ("เสร็จสิ้น: Loa Ding ยังคงมีอยู่");
จากรายการ 11 ดูขั้นตอนการดำเนินการของวิธีการ DoLoad StandardManager มีดังนี้:
ล้างข้อมูลเซสชันที่ดูแลโดยแคชเซสชัน
เรียกใช้วิธีไฟล์เพื่อส่งคืนไฟล์ถาวรเซสชันภายใต้บริบทปัจจุบันเช่น: d:/workspace/tomcat7.0/work/catalina/localhost/host-manager/sessions.ser;
เปิดสตรีมอินพุตของเซสชันไฟล์ถาวรและห่อหุ้มเป็น CustomObjectInputStream;
อ่านจำนวนเซสชันที่คงอยู่จากเซสชันไฟล์ถาวรจากนั้นอ่านข้อมูลเซสชันทีละตัวและใส่ลงในแคชเซสชัน
ณ จุดนี้การแนะนำการเปิดตัว StandardManager อยู่ที่นี่