ในหัวข้อนี้ ฉันอยากจะพูดอย่างตรงไปตรงมาเกี่ยวกับความเข้าใจของฉันเกี่ยวกับเซิร์ฟเล็ต คอนเทนเนอร์เซิร์ฟเล็ตคืออะไร เฟรมเวิร์กส่วนหน้าของเว็บส่วนใหญ่หรือทั้งหมดคืออะไร และยังกล่าวถึงหัวข้อว่าคอนเทนเนอร์เซิร์ฟเล็ตและแอปพลิเคชันเซิร์ฟเวอร์เกี่ยวข้องอย่างไร ซึ่งกันและกันและเซิร์ฟเล็ตและคอนเทนเนอร์เว็บเซิร์ฟเวอร์ ปราศจากสิ่งที่น่าสมเพช  เรามาพูดถึง Java EE, servlets และคอนเทนเนอร์กันดีกว่า - 1ก่อนที่จะเริ่มการสนทนา ฉันอยากจะทราบว่าฉันคาดหวังจริงๆ ว่าจะมีการพูดคุยกัน เพราะ... ในที่นี้ฉันไม่ต้องการให้โค้ดแม้แต่ชิ้นเดียว แต่แค่อยากจะพูดถึงสาระสำคัญซึ่งสามารถระบุเป็นคำพูดได้เสมอ ฉันจะพยายามสรุปประเด็นทั้งหมดที่ฉันไม่ชัดเจนเมื่อฉันเริ่มครั้งแรก เมื่อฉันถามคำถามในฟอรัมต่างๆ ในหัวข้อว่าคอนเทนเนอร์เซิร์ฟเล็ต Tomcat แตกต่างจากแอปพลิเคชันเซิร์ฟเวอร์ใด ๆ อย่างไร เช่น WebSphere หรือ Geronimo คนที่กล้าตอบคือคนโง่ที่ไม่สามารถพูดอะไรได้นอกจาก "ดูที่ Wikipedia" หรือ " พูดยากนะ แอปพลิเคชันเซิร์ฟเวอร์ นี่เป็นโครงสร้างพื้นฐานที่ซับซ้อนสำหรับแอปพลิเคชันขององค์กร ซึ่ง..." บลา บลา บลา ฉันทนคนแบบนั้นไม่ได้ และฉันก็เดาว่าพวกคุณส่วนใหญ่ก็ทนไม่ได้เช่นกัน เราจะแก้ไขความอยุติธรรมทางประวัติศาสตร์ ไป…

เซิร์ฟเล็ต

ไม่ว่าใครจะว่ายังไง เซิร์ฟเล็ตก็คือเว็บเพจที่เขียนด้วยภาษาจาวา บางคนอาจบอกว่าฉันผิดและเซิร์ฟเล็ตเป็นเว็บแอปพลิเคชัน และแนวคิดเหล่านี้มีความแตกต่างกัน แต่ก็ไม่เป็นเช่นนั้น ตอนนี้ไม่มีความแตกต่างและไซต์ที่เขียนด้วย PHP ก็สามารถเรียกเว็บแอปพลิเคชันได้อย่างปลอดภัยเช่นกัน ตอนนี้มันเป็นเรื่องธรรมชาติโดยสมบูรณ์ เพราะว่า... php รองรับ OOP อย่างสมบูรณ์ และ CMS เช่น Joomla ก็ใช้งานสิ่งนี้อย่างจริงจัง servlet ในระดับโค้ดคืออะไร? นี่คือคลาสที่มีวิธีการหลายวิธีที่จะเข้าสู่โหมดสลีปและดูว่ามีคนเข้าถึงผ่านคำขอ GET หรือ POST HTTP หรือไม่ เหล่านั้น. เราพิมพ์คำขอ GET ลงในเบราว์เซอร์ วิธีการที่สอดคล้องกันของคลาสเซิร์ฟเล็ตจะยอมรับ จากนั้นจึงสร้างการตอบกลับในรูปแบบของหน้า HTML ในความหมายคลาสสิกของเซิร์ฟเล็ต ตามที่ Sun คิดขึ้น หน้านี้ถูกส่งไปยังไคลเอนต์ทีละบรรทัด เริ่มต้นด้วยบรรทัด <!DOCTYPE htm>> และลงท้ายด้วยบรรทัด </html> ดังนั้นใน Java จึงมีคลาสเซิร์ฟเล็ตพื้นฐานที่เรียกว่าServlet. นอกจากนี้ยังมีคลาสอื่นๆ อีกมากมายที่สืบทอดมาจากคลาสพื้นฐานนี้ และด้วยเหตุนี้จึงขยายฟังก์ชันการทำงานออกไป นั่นคือสิ่งที่เซิร์ฟเล็ตเป็น - ไม่มีอะไรเพิ่มเติม มันเป็นเพียงอะนาล็อก Java ของโค้ด PHP ซึ่งดำเนินการบนเซิร์ฟเวอร์เช่นกัน และมีเพียงการตอบสนองต่อคำขอของเว็บเบราว์เซอร์ในรูปแบบของหน้าเว็บเท่านั้นที่ถูกส่งไปยังไคลเอนต์ ทั้งหมด.

เฟรมเวิร์กส่วนหน้าของเว็บ

คำบรรยายมีความซับซ้อนและโดยปกติแล้วพวกเขาจะเขียนแค่เฟรมเวิร์กส่วนหน้าหรือแม้แต่เว็บปากกระบอกปืนแต่ฉันตัดสินใจเน้นที่นี่ว่าเมื่อเราพูดถึงเฟรมเวิร์กส่วนหน้า เรากำลังพูดถึง GUI สำหรับการทำงานกับ Java ผ่านเว็บเบราว์เซอร์ เหล่านั้น. เรากำลังพูดถึงเว็บไซต์ใน Java อีกครั้งเช่น เกี่ยวกับเซิร์ฟเล็ต ฟรอนต์เอนด์เกือบทุกประเภทคืออะไร เช่น Apache Struts มันเป็นเพียงชุดของคลาสที่ขยายคลาสServletพื้นฐาน ไม่มีอะไรเพิ่มเติม เหล่านั้น. มันเป็นเพียงวิธีที่แตกต่างในการสร้างเซิร์ฟเล็ตปกติเดียวกัน เพียงแต่ว่าผู้พัฒนาเฟรมเวิร์กนี้ (หรืออีกนัยหนึ่งคือผู้พัฒนาเทคโนโลยีนี้) พิจารณาว่าการเพิ่มคลาสพื้นฐานServletด้วยวิธีการบางอย่างจะสะดวกกว่าสำหรับโปรแกรมเมอร์มากกว่าฟังก์ชันการทำงานที่น้อยอย่างที่เซิร์ฟเล็ตแบบคลาสสิกจาก Sun/Oracle มี.

หน้าเจเอสพี

เกือบจะในทันที นักพัฒนาแนวคิด Java servlet ก็เข้ามาในความคิดอีกประการหนึ่ง เนื่องจากเรากำลังเขียนเซิร์ฟเล็ต หน้าที่คือส่งหน้า html ไปยังไคลเอนต์ ดังนั้นการเขียนหน้า html นี้ทันทีอาจถูกต้องมากกว่า และหากคุณต้องการตรรกะบางอย่างใน Java เพียงแค่แทรกโดยตรง ลงใน html หากไม่ชัดเจนยิ่งขึ้น วลีนี้อาจช่วยได้: หน้า jsp เป็นอะนาล็อกของหน้า php ยาก? แล้วจะอธิบายอีกครั้งครับ. เมื่อเขียนเพจด้วย PHP เราควรทำอย่างไร? เรามี html แบบคงที่ และเมื่อเราต้องการแทรกตรรกะใดๆ ใน PHP เช่น ลูปและเงื่อนไข เราก็จะแทรกมันเข้าไปในเนื้อหาของแท็ <?php … ?>ก ด้วย jsp ทุกอย่างจะเหมือนกัน มีเพียงตรรกะเท่านั้นที่เขียนด้วย Java ล้วนๆ โดยโค้ดจะถูกแทรกลงในเนื้อหาของแท็<% … %>ก กลับมาที่แนวคิดของเซิร์ฟเล็ตอีกครั้ง โดยพื้นฐานแล้ว เพจ JSP นั้นเป็นเซิร์ฟเล็ต แต่เขียนแตกต่างออกไปเล็กน้อย ในเซิร์ฟเล็ตทั่วไป เราเขียนวิธีการที่ใช้ตรรกะบางอย่าง และสร้างหน้า HTML สำหรับไคลเอนต์ตามผลลัพธ์ หลังจากนั้นไม่นานนักพัฒนาเซิร์ฟเล็ตก็เริ่มคิดว่า: จะเกิดอะไรขึ้นหากไม่มีตรรกะในวิธีการและเกือบจะเกิดเพียงการก่อตัวของหน้า html เท่านั้น การเขียนหน้า html ลงในทันทีจะไม่ง่ายกว่าหรือ สิ่งใดที่จะทำให้การแทรก Java น้อยที่สุด รหัส สิ่งสุดท้ายเกี่ยวกับหน้า jsp ในครั้งแรกที่มีการเข้าถึงเพจดังกล่าว เพจดังกล่าวจะถูกคอมไพล์เป็นเซิร์ฟเล็ตแล้วจึงดำเนินการ คำขอครั้งต่อไปไปยังหน้า jsp นี้จะเร็วขึ้นเนื่องจาก มันจะถูกคอมไพล์แล้วและจะต้องดำเนินการเท่านั้น

ภาชนะเสิร์ฟ

ดังนั้นเราจึงเขียนคลาสเซิร์ฟเล็ตหรือเพจ JSP อะไรต่อไป? จะผลักพวกมันเข้าไปในเว็บเซิร์ฟเวอร์ได้อย่างไรเช่น apache เพื่อที่จะสามารถส่งพวกมันไปยังเว็บเบราว์เซอร์ของผู้ใช้ได้ เว็บเซิร์ฟเวอร์สามารถส่งได้เฉพาะ html เท่านั้น และหากเพจของเรามีโค้ด php เว็บเซิร์ฟเวอร์จะส่งผ่านเพจนั้นผ่านล่ามที่แปล php เป็น html ก่อน จากนั้นผลลัพธ์จะถูกส่งไปยังไคลเอนต์เท่านั้น สิ่งเดียวกันนี้เกิดขึ้นกับเซิร์ฟเล็ต - ก่อนที่จะส่ง เซิร์ฟเล็ตจะต้องดำเนินการเพื่อสร้างเพจ HTML และคอนเทนเนอร์เซิร์ฟเล็ตคือสิ่งที่รับผิดชอบในการรันเซิร์ฟเล็ตและโค้ดเพจ jsp เหล่านั้น. คอนเทนเนอร์เซิร์ฟเล็ตสำหรับจาวาเป็นอะนาล็อกของโมดูลล่าม php ในเว็บเซิร์ฟเวอร์ ดังนั้น เมื่อผู้ใช้ป้อนที่อยู่ในเว็บเบราว์เซอร์ คำขอจะถูกส่งไปยังเว็บเซิร์ฟเวอร์ เว็บเซิร์ฟเวอร์จะเข้าใจว่ากำลังร้องขอเซิร์ฟเล็ต และส่งคำขอไปยังคอนเทนเนอร์เซิร์ฟเล็ต หลังจากนี้ คอนเทนเนอร์เซิร์ฟเล็ตจะเรียกใช้งานเซิร์ฟเล็ต โดยส่งเพจ HTML ที่เป็นผลลัพธ์ไปยังเว็บเซิร์ฟเวอร์ ซึ่งในทางกลับกัน จะส่งคืนให้กับไคลเอนต์ เซิร์ฟเล็ตคอนเทนเนอร์สามารถรันได้ด้วยตัวเองหรือไม่ เช่น ไม่มีเว็บเซิร์ฟเวอร์ใช่ไหม? บางอย่างเช่น Tomcat สามารถทำได้อย่างแน่นอน และหากเราต้องการสร้างไซต์ที่ไม่มีหน้า html อื่นใดยกเว้นหน้าที่ใช้เซิร์ฟเล็ต คอนเทนเนอร์เซิร์ฟเล็ตก็เพียงพอแล้วสำหรับเรา แต่ถ้าเราต้องการรวมไซต์จากเซิร์ฟเล็ตและเช่นหน้า PHP เราจะต้องติดตั้งเว็บเซิร์ฟเวอร์ นอกจากนี้ ไม่ใช่ทุกเว็บเซิร์ฟเวอร์ที่มีคอนเทนเนอร์เซิร์ฟเล็ตรวมอยู่ด้วยตามค่าเริ่มต้น แต่เกือบทั้งหมดจะอนุญาตให้คุณติดตั้งเป็นปลั๊กอินได้ ดังนั้นหากเราต้องการเปิดตัวเว็บไซต์ของเราบนบางโฮสติ้งบนอินเทอร์เน็ตซึ่ง Apache มีแนวโน้มที่จะทำงานมากที่สุด เราจะต้องถามผู้ให้บริการว่าคอนเทนเนอร์เซิร์ฟเล็ตเชื่อมต่ออยู่หรือไม่

จาวา EE

มีสิ่งที่เรียกว่า JavaSE (Java Standard Edition) แนวคิดนี้รวมคลาสทั้งหมดjavaสำหรับการใช้งานที่เราจำเป็นต้องนำเข้า (เช่นjava.util.Date) หรือแม้กระทั่งไม่จำเป็นต้องทำเช่นนี้ (เช่นStringเนื่องจากอยู่ในแพ็คเกจjava.lang) และมี Java EE (Java Enterprise Edition) คลาสเหล่านี้เป็นของ Sun/Oracle เช่นกัน แต่ข้อแตกต่างเพียงอย่างเดียวคือคลาสเหล่านี้เริ่มใช้ในโปรเจ็กต์ได้ยากกว่า เส้นธรรมดาimport…คงไม่พอ เพราะ... โครงการจะไม่รวบรวม เพื่อแก้ไขสถานการณ์ คุณจะต้องค้นหา ไฟล์ไลบรารี javaee.jarและรวมไว้ในโปรเจ็กต์ ซึ่งสามารถทำได้ผ่านคุณสมบัติของโครงการในสภาพแวดล้อมการพัฒนา มักกล่าวกันว่ากระบวนการเชื่อมต่อนี้เรียกว่า: ลงทะเบียนชื่อเล่น jar ในเส้นทางการ buildหรือclasspathของโปรเจ็กต์

เซิร์ฟเวอร์แอปพลิเคชัน

ทีนี้ลองจินตนาการว่าเราได้รวบรวมโปรเจ็กต์เซิร์ฟเล็ตของเราที่ใช้ Java EE แล้ว ทุกอย่างเยี่ยมยอด แต่ตอนนี้เราต้องวางคลาสที่คอมไพล์แล้วของเราไว้ในคอนเทนเนอร์เซิร์ฟเล็ต สมมติว่าพวกเขาทำมัน ใบสมัครของเราจะใช้งานได้หรือไม่? คำตอบคือไม่ เมื่อเข้าถึงเซิร์ฟเล็ต จะมีข้อยกเว้นปรากฏขึ้นเพื่อระบุว่าไม่พบคลาสบางคลาส ทำไม เพราะเรา "หลอกลวง" คอมไพเลอร์โดยการลื่นjavaee.jar в classpathไถลนั่นคือ คอมไพเลอร์เห็นว่ามีคลาสจาก Java EE อยู่แล้วและสงบลง แต่คอนเทนเนอร์เซิร์ฟเล็ตไม่เห็นคลาสเหล่านี้ แต่เห็นลิงก์ไปยังคลาสเหล่านั้นจากเซิร์ฟเล็ตของเรา สถานการณ์นี้สามารถแก้ไขได้ภายในคอนเทนเนอร์เซิร์ฟเล็ตหรือไม่ ใช่แล้ว คุณเพียงแค่ต้องเพิ่มไฟล์ไลบรารี javaee.jar ลงในโฟลเดอร์ที่มีเซิร์ฟเล็ต ของเราในคอนเทนเนอร์เซิร์ฟเล็ต ตอนนี้ลองจินตนาการว่าจะมีโปรเจ็กต์ดังกล่าวมากมาย และพวกเขาทั้งหมดทำงานในคอนเทนเนอร์เซิร์ฟเล็ต Tomcat เดียว ซึ่งหมายความว่าคุณจะต้องคัดลอกไฟล์ jar นี้ไปยังโฟลเดอร์ของแต่ละเซิร์ฟเล็ต สิ่งนี้ไม่สะดวกและผิด สถานการณ์ได้รับการแก้ไขโดยการแนะนำแนวคิดของแอปพลิเคชันเซิร์ฟเวอร์ ซึ่งไฟล์นี้มีอยู่ในสำเนาเดียวมานานแล้ว และเซิร์ฟเล็ตทั้งหมดสามารถเข้าถึงได้ และไม่มีสำเนาของตัวเอง ในความคิดของฉันมันสะดวกและสมเหตุสมผลมาก โดยธรรมชาติแล้วความยุ่งยากทั้งหมดไม่ได้เกิดจากไฟล์ jar ไฟล์เดียว (ฉันยกตัวอย่างไว้) - มีไฟล์ดังกล่าวมากมาย แต่นั่นไม่ใช่ทั้งหมดที่เซิร์ฟเวอร์แอปพลิเคชันมอบให้เรา แอปพลิเคชันเซิร์ฟเวอร์เองสามารถรักษาการเชื่อมต่อกับทรัพยากรจำนวนมาก เช่น ฐานข้อมูล ในกรณีนี้ เซิร์ฟเล็ตของเราอาจไม่เปิดการเชื่อมต่อดังกล่าวเอง แต่เพียงรับจากแอปพลิเคชันเซิร์ฟเวอร์ ในคอนเทนเนอร์เซิร์ฟเล็ต สิ่งนี้เป็นไปไม่ได้ เพราะ... คอนเทนเนอร์คือแอปพลิเคชันเซิร์ฟเวอร์แบบแยกส่วนในระดับหนึ่ง ในคอนเทนเนอร์ เซิร์ฟเล็ตจะต้องสร้างการเชื่อมต่อกับฐานข้อมูลเสมอ อะไรประมาณนี้... war-archive war-archive คืออะไร? WAR คือเว็บเก็บถาวร อันที่จริงแล้ว มันเป็นเพียงไฟล์ zip เช่นเดียวกับขวดอื่นๆ โดยพื้นฐานแล้ว นี่เป็นเพียงวิธีการอัดเว็บไซต์ของเราซึ่งประกอบด้วยหน้าเว็บ หน้า jsp และคลาสเซิร์ฟเล็ตจำนวนมากให้เป็นไฟล์ zip ไฟล์เดียว web.xml web.xml เป็นสิ่งที่เรียกว่าตัวอธิบายการปรับใช้ นี่คือไฟล์ที่อธิบายอย่างโง่เขลาว่าคำขอบรรทัดของเว็บเบราว์เซอร์ใดที่จะส่งไปยังคลาสเซิร์ฟเล็ตใดสำหรับการประมวลผล เพื่อไม่ให้คอนเทนเนอร์เซิร์ฟเล็ตสับสน เซิร์ฟเล็ตใดรับผิดชอบอะไร โดยทั่วไปแล้ว ใน Java การอธิบายการตั้งค่าในไฟล์ xml ทุกประเภทเป็นเรื่องที่ทันสมัยมาก แต่เมื่อเร็ว ๆ นี้มีแนวโน้มที่จะเปลี่ยนจากประเพณีนี้ คุณถามอย่างไร? และผ่านคำอธิบายประกอบ คลาสคำอธิบายประกอบเองไม่ได้ทำอะไรเลย คลาสเหล่านี้ถูกสร้างขึ้นเพื่ออธิบายการตั้งค่าทุกประเภท (ข้อมูลเมตา) ไม่ได้อยู่ในไฟล์ xml แยกต่างหาก แต่อยู่ในโค้ดโดยตรง สบายมาก. อย่างไรก็ตาม ขณะนี้มีขั้นตอนกลางบางอย่าง เมื่อการตั้งค่าบางอย่างระบุโดยคำอธิบายประกอบ และบางส่วนระบุโดย xml ซึ่งอาจทำให้เกิดความสับสนได้ เนื่องจาก คุณดูที่ xml และดูการตั้งค่าหนึ่ง แต่ตามคำอธิบายประกอบนั้นมีอีกการตั้งค่าหนึ่ง อันไหนมีลำดับความสำคัญสูงสุด? ใครจะรู้…

บทสรุป

เขียนเรื่องนี้แล้วคิดว่าการรีวิวสั้นๆ แบบนี้คงไม่ช่วยใครได้ เพราะ... ไม่มีรายละเอียดเฉพาะเจาะจงและไม่มีตัวอย่างใดๆ แต่ในทางกลับกัน อย่าลบสิ่งที่เขียนไว้ก็ปล่อยให้เป็นเช่นนั้น