JavaRush /จาวาบล็อก /Random-TH /จาก Hello World ไปจนถึง Spring Web MVC และเซิร์ฟเล็ตเกี่ย...
Viacheslav
ระดับ

จาก Hello World ไปจนถึง Spring Web MVC และเซิร์ฟเล็ตเกี่ยวข้องกับมันอย่างไร

เผยแพร่ในกลุ่ม
จาก Hello World ไปจนถึง Spring Web MVC และเซิร์ฟเล็ตเกี่ยวข้องกับมันอย่างไร - 1

การแนะนำ

ดังที่เราทราบ ความสำเร็จของ Java เกิดขึ้นอย่างแน่นอนด้วยวิวัฒนาการของซอฟต์แวร์ที่มุ่งมั่นที่จะเชื่อมต่อกับเครือข่าย ดังนั้นเราจะใช้แอปพลิเคชันคอนโซลปกติ " Hello World " เป็นพื้นฐานและทำความเข้าใจว่าจำเป็นต้องมีอะไรบ้างในการเป็นแอปพลิเคชันเครือข่ายจากแอปพลิเคชันคอนโซล ดังนั้นก่อนอื่นคุณต้องสร้างโปรเจ็กต์ Java โปรแกรมเมอร์เป็นคนขี้เกียจ ในสมัยก่อนประวัติศาสตร์ เมื่อบางคนกำลังล่าแมมมอธ บางตัวก็นั่งและพยายามไม่สับสนในไลบรารี Java และโครงสร้างไดเร็กทอรีที่หลากหลาย เพื่อให้นักพัฒนาสามารถควบคุมกระบวนการสร้างแอปพลิเคชันเพื่อที่เขาจะได้เขียนว่า "ฉันต้องการไลบรารี่ของเช่นนั้นและเวอร์ชัน 2" จึงมีเครื่องมือพิเศษ - สร้างระบบ สองอันที่มีชื่อเสียงที่สุดคือMavenและGradle สำหรับบทความนี้เราจะใช้ Gradle หากก่อนหน้านี้เราจะต้องสร้างโครงสร้างไดเร็กทอรีด้วยตัวเอง ตอนนี้ Gradle โดยใช้Gradle Init Pluginช่วยให้เราสามารถสร้างโปรเจ็กต์ Java ด้วยโครงสร้างไดเร็กทอรีและคลาสหลักพื้นฐานในคำสั่งเดียว: gradle init --type java-application คำสั่งนี้ดำเนินการเริ่มต้น (init) สำหรับ เราเป็นแอปพลิเคชัน Java (java-application ) พร้อมคอนโซล Hello World หลังจากเสร็จสิ้น ไฟล์จะปรากฏในไดเร็กทอรี - build.gradle นี่คือสคริปต์การสร้าง ของเรา - นั่นคือสคริปต์บางตัวสำหรับการสร้างแอปพลิเคชันพร้อมคำอธิบายว่าต้องดำเนินการอะไรบ้างสำหรับสิ่งนี้ ลองเปิดมันและเพิ่มบรรทัดลงไป: jar.baseName = 'webproject' Gradle ช่วยให้คุณสามารถดำเนินการต่าง ๆ ในโครงการและการกระทำเหล่านี้เรียกว่างาน โดยการรันคำสั่ง (งาน) ไฟล์ JAR จะถูกสร้างขึ้น gradle buildใน ไดเร็กทอรี /build/libs และอย่างที่คุณเดาได้ ตอนนี้ชื่อของมันจะเป็นwebproject.jar แต่ถ้าเราดำเนินการjava -jar ./build/libs/webproject.jarเราจะได้รับข้อผิดพลาด: no main manifest attribute. เนื่องจากสำหรับแอปพลิเคชัน Java คุณต้องแนบรายการ - นี่คือคำอธิบายเกี่ยวกับวิธีการทำงานกับแอปพลิเคชัน วิธีการรับรู้ จากนั้น JVM ซึ่งจะรันแอปพลิเคชัน Java จะรู้ว่าคลาสใดเป็นจุดเริ่มต้นของโปรแกรมและข้อมูลอื่น ๆ (เช่น classpath) หากเราพิจารณาเนื้อหาของสคริปต์บิลด์ให้ละเอียดยิ่งขึ้น เราจะเห็นว่ามีการเชื่อมต่อปลั๊กอินอยู่ ตัวอย่างเช่น: apply plugin: 'java' ถ้าเราไปที่ หน้า Gradle Java Plugin เราจะเห็นว่าเราสามารถกำหนดค่ารายการได้:
jar {
    manifest {
        attributes 'Main-Class': 'App'
    }
}
คลาสหลักซึ่งเป็นจุดเริ่มต้นของโปรแกรมถูกสร้างขึ้นสำหรับเราโดย Gradle Init Plugin และยังระบุไว้ในพารามิเตอร์ mainClassName ด้วย แต่สิ่งนี้ไม่เหมาะกับเราเพราะว่า... การตั้งค่านี้อ้างอิงถึงปลั๊กอินอื่นGradle Application Plugin ดังนั้นเราจึงมีแอปพลิเคชัน Java ที่แสดง Hello World บนหน้าจอ แอปพลิเคชัน Java นี้บรรจุอยู่ใน JAR (Java ARchive) มันเรียบง่าย ใช้คอนโซล และไม่ทันสมัย จะเปลี่ยนให้เป็นเว็บแอปพลิเคชั่นได้อย่างไร?
От Hello World до Spring Web MVC и при чём тут сервлеты - 2

เซิร์ฟเล็ต API

เพื่อให้ Java สามารถทำงานร่วมกับเครือข่ายได้ ข้อกำหนดที่เรียกว่าServlet API ปรากฏขึ้นในสมัย โบราณ ข้อกำหนดนี้อธิบายการโต้ตอบระหว่างไคลเอ็นต์และเซิร์ฟเวอร์ การรับข้อความจากไคลเอ็นต์ (เช่น เบราว์เซอร์) และการส่งการตอบกลับ (เช่น พร้อมข้อความในหน้าเว็บ) โดยปกติแล้วมีการเปลี่ยนแปลงมากมายตั้งแต่นั้นมา แต่ประเด็นก็คือเพื่อให้แอปพลิเคชัน Java กลายเป็นเว็บแอปพลิเคชันนั้น Servlet API จึงถูกใช้ เพื่อไม่ให้เป็นการคาดเดาอย่างไม่มีมูล เรามาเลือกข้อมูลจำเพาะนั้นกันดีกว่า: JSR-000340 JavaTM Servlet 3.1 ก่อนอื่นเราสนใจ " บทที่ 1: ภาพรวม " มันอธิบายแนวคิดพื้นฐานที่เราต้องเข้าใจ ก่อนอื่น servlet คืออะไร? บทที่ " 1.1 Servlet คืออะไร " บอกว่าServletเป็นส่วนประกอบ Java ที่ได้รับการจัดการโดยคอนเทนเนอร์และสร้างเนื้อหาแบบไดนามิก เช่นเดียวกับส่วนประกอบ Java อื่นๆ servlet คือคลาส Java ที่ถูกคอมไพล์เป็น bytecode และสามารถโหลดลงในเว็บเซิร์ฟเวอร์โดยใช้เทคโนโลยี Java สิ่งสำคัญคือเซิร์ฟเล็ตโต้ตอบกับเว็บไคลเอ็นต์ (เช่น เบราว์เซอร์) ภายในกรอบของกระบวนทัศน์คำขอ/ตอบกลับ ซึ่งดำเนินการโดยคอนเทนเนอร์เซิร์ฟเล็ต ปรากฎว่า Servlets อาศัยอยู่ใน Servlet Container บางประเภท นี่คืออะไร? ในบท " 1.2 Servlet Container คืออะไร " ว่ากันว่าServlet Containerเป็นส่วนหนึ่งของเว็บเซิร์ฟเวอร์หรือแอปพลิเคชันเซิร์ฟเวอร์ที่ให้บริการเครือข่ายซึ่งมีการส่งคำขอและส่งการตอบสนอง Servlet Container นี้จัดการวงจรชีวิตของเซิร์ฟเล็ต Servlet Containers ทั้งหมดจำเป็นต้องรองรับโปรโตคอล HTTP เป็นอย่างน้อย แต่อาจรองรับโปรโตคอลอื่นได้ ตัวอย่างเช่น HTTPS สิ่งสำคัญคือ Servlet Container สามารถกำหนดข้อจำกัดที่เกี่ยวข้องกับความปลอดภัยบนสภาพแวดล้อมที่เซิร์ฟเล็ตถูกดำเนินการได้ สิ่งสำคัญคือตาม " 10.6 Web Application Archive File " เว็บแอปพลิเคชันจะต้องได้รับการบรรจุในไฟล์ WAR (Web ARchive) นั่นคือตอนนี้เราต้องลบ jar และปลั๊กอินแอปพลิเคชันของเราเพื่ออย่างอื่น และนี่คือปลั๊กอิน Gradle WAR และแทนที่จะระบุ jar.baseName ให้ระบุ war.baseName Because เนื่องจากเราไม่ได้ใช้ปลั๊กอิน jar อีกต่อไป เราจึงได้ลบการตั้งค่ารายการออกด้วย เมื่อเราเปิดตัว JAR จำเป็นต้องบอก Java Virtual Machine (JVM) ถึงวิธีทำงานกับแอปพลิเคชันของเราผ่านทาง Manifest เพราะ JVM กำลังรันอยู่ เห็นได้ชัดว่าเว็บแอปพลิเคชันนั้นดำเนินการโดยเว็บเซิร์ฟเวอร์บางประเภท ปรากฎว่าเขาจำเป็นต้องบอกวิธีการทำงานกับเว็บแอปพลิเคชันของเราหรือไม่? และปรากฎว่าใช่ เว็บแอปพลิเคชันมีแถลงการณ์พิเศษของตัวเอง เรียกว่าDeployment Descriptor ส่วนทั้งหมดมีไว้สำหรับมัน: " 14. Descriptor การปรับใช้ " มีส่วนสำคัญ: " บทที่ 10:" มันพูดถึงว่าเว็บแอปพลิเคชันคืออะไรจากมุมมองของ Servlet API ตัวอย่างเช่นในบท " 10.5 Directory Structure " มีการระบุว่า Deployment Descriptor ควรอยู่ที่ใด: /WEB-INF/web.xmlจะวาง WEB-INF ไว้ที่ไหน? ตามที่ระบุไว้ในปลั๊กอิน Gradle WAR มันจะเพิ่มเลย์เอาต์ ใหม่ : src/main/webappดังนั้นเรามาสร้างไดเร็กทอรีดังกล่าวภายในเราจะสร้างไดเร็กทอรี WEB-INF และภายในเราจะสร้างไฟล์ web.xml สิ่งสำคัญคือไดเร็กทอรี เรียกว่า WEB-INF ไม่ใช่ META-INF ลองคัดลอกมาจากตัวอย่าง XML " 14.5.1 A Basic Example ":
От Hello World до Spring Web MVC и при чём тут сервлеты - 3
ดังที่เราเห็น เอกสาร XML ใช้สำหรับการกำหนดค่า เอกสาร XML เพื่อให้ถือว่าถูกต้อง (ถูกต้อง) จะต้องสอดคล้องกับ "สคีมา" บางอย่าง คุณสามารถมองสิ่งนี้ว่าเป็นอินเทอร์เฟซชนิดหนึ่งสำหรับเอกสาร XML สคีมาจะระบุองค์ประกอบที่สามารถเป็นได้ในเอกสาร XML ประเภทข้อมูลที่สามารถกำหนดองค์ประกอบ ลำดับ ความต้องการ และลักษณะอื่นๆ ตัวอย่างที่คัดลอกมาจากเอกสารระบุเวอร์ชัน 2.5 แต่เราต้องการใช้เวอร์ชัน 3.1 โดยปกติแล้ว ข้อมูลจำเพาะจะเปลี่ยนไปตามเวอร์ชันที่เปลี่ยนไปและมีการเพิ่มฟีเจอร์ใหม่ๆ ดังนั้น คุณจึงจำเป็นต้องใช้สคีมาอื่นนอกเหนือจากที่ใช้สำหรับเวอร์ชัน 2.5 (web-app_2_5.xsd) ฉันควรใช้โครงร่างใดสำหรับเวอร์ชัน 3.1 เอกสารจะช่วยเราในเรื่องนี้ในบท “ 14.3 Deployment Descriptor ” ซึ่งระบุว่าspecification is available at http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd นั่นคือ เราจำเป็นต้องแทนที่ลิงก์ไปยังสคีมาด้วย xsd ที่ระบุทุกที่ โดยไม่ลืมที่จะเปลี่ยนversion="2.5"เป็น 3.1 และยังเปลี่ยนเนมสเปซทุกที่ ( xmlns และใน xsi:schemaLocation) พวกเขาระบุว่าเราจะทำงานภายในเนมสเปซใด (พูดง่ายๆ ก็คือ ชื่อองค์ประกอบใดที่เราสามารถใช้ได้) หากคุณเปิดไฟล์สคีมา targetNamespace จะมีเนมสเปซเดียวกันกับที่เราควรระบุ:
От Hello World до Spring Web MVC и при чём тут сервлеты - 4
อย่างที่เราจำได้ ในไฟล์ Manifest of the Jar เราได้เขียนคลาสที่เราต้องการใช้ จะทำอย่างไรที่นี่? ที่นี่เราจำเป็นต้องระบุคลาสเซิร์ฟเล็ตที่เราต้องการใช้เมื่อเราได้รับคำขอจากเว็บไคลเอ็นต์ คำอธิบายสามารถอ่านได้ในบท " 14.4 Deployment Descriptor Diagram " มันจะมีลักษณะเช่นนี้:
От Hello World до Spring Web MVC и при чём тут сервлеты - 5
ทุกอย่างเรียบง่ายที่นี่ มีการประกาศเซิร์ฟเวอร์เล็ต จากนั้นแมปกับเทมเพลตที่กำหนด ในกรณีนี้ บน /app เมื่อดำเนินการแม่แบบ วิธีการเซิร์ฟเล็ตจะถูกดำเนินการ เพื่อความสวยงาม ควรโอนคลาส App ไปที่แพ็คเกจ โดยไม่ลืมแก้ไขการกำหนดค่า xml แต่นั่นไม่ใช่ทั้งหมด แอปจะต้องเป็นเซิร์ฟเล็ต การเป็นเซิร์ฟเล็ตหมายความว่าอย่างไร? ซึ่งหมายความว่าเราต้องสืบทอดจากHttpServlet ตัวอย่างสามารถดูได้ในบท " 8.1.1 @WebServlet " ตามนั้นคลาส App ของเราจะมีลักษณะดังนี้:
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class App extends HttpServlet {
    public String getGreeting() {
        return "Hello world.";
    }

	public void doGet(HttpServletRequest request, HttpServletResponse response) {
		response.setContentType("text/html");
		try {
			response.getWriter().println(getGreeting());
		} catch (IOException e) {
			throw new IllegalStateException(e);
		}
	}
}
แต่โครงการของเรายังไม่พร้อม เนื่องจากตอนนี้เราพึ่งพา Servlet API เวอร์ชัน 3.1 ซึ่งหมายความว่าในสคริปต์บิลด์ของเรา เราจำเป็นต้องระบุการพึ่งพา Servlet API JVM จำเป็นต้องรู้ว่าสิ่งที่คุณเขียนในโค้ดนั้นถูกต้องและใช้งานอย่างไร อย่างที่เราจำได้ ข้อมูลจำเพาะนั้นเป็นเพียงอินเทอร์เฟซที่อธิบายว่ามันควรทำงานอย่างไร และการใช้งานนั้นอยู่ทางฝั่งเว็บเซิร์ฟเวอร์ ดังนั้น หาก ไม่มีServlet API จะมีการค้นหาไลบรารีที่ต้องการบน Maven Central: javax.servlet-api และ เพิ่มรายการลงใน บล็อก การพึ่งพา ในพื้นที่เก็บข้อมูล Maven อย่างที่คุณเห็น มันบอกว่าให้มา ก่อนที่จะใช้การขึ้นต่อกัน คุณต้องระบุขอบเขต Gradle ไม่มีขอบเขตชื่อ "ระบุ" แต่มีขอบเขต " คอมไพล์เท่านั้น " ดังนั้นเราจะระบุว่า: providedCompile 'javax.servlet:javax.servlet-api:3.1.0' เอ่อ ดูเหมือนว่าทุกอย่างจะเรียบร้อยดีใช่ไหม? Gradle Build จะสร้างโปรเจ็กต์ของเราเป็นไฟล์ WAR และเราควรทำอย่างไรต่อไปกับมัน? ก่อนอื่นเราต้องมีเว็บเซิร์ฟเวอร์ ใน Google เราเขียน " รายการเว็บเซิร์ฟเวอร์ java " และดูรายการเว็บเซิร์ฟเวอร์ เรามาเลือกจากรายการนี้กันเช่นTomCat ไปที่ เว็บไซต์ Apache Tomcatดาวน์โหลดเวอร์ชันล่าสุด (ปัจจุบันคือเวอร์ชัน 9) เป็นไฟล์ zip (หากสำหรับ Windows) แตกไฟล์ลงในไดเร็กทอรีบางแห่ง ไชโย เรามีเว็บเซิร์ฟเวอร์ จากไดเรกทอรีของเว็บเซิร์ฟเวอร์ใน ไดเรกทอรีย่อย bin เราจะดำเนินการ catalinaจากบรรทัดคำสั่งและดูตัวเลือกที่มี มาทำกัน: catalina start. แต่ละเว็บเซิร์ฟเวอร์มีไดเร็กทอรีที่เว็บเซิร์ฟเวอร์ตรวจสอบ หากไฟล์แอปพลิเคชันเว็บปรากฏขึ้น แสดงว่าเว็บเซิร์ฟเวอร์เริ่มทำการติดตั้ง การติดตั้งนี้เรียกว่าการปรับใช้หรือการปรับใช้ ใช่ ใช่ นั่นเป็นเหตุผลว่าทำไม " Descriptor การนำไปใช้งาน " นั่นคือวิธีการปรับใช้แอปพลิเคชันอย่างเหมาะสม ใน Tomcat ไดเรกทอรีนี้คือwebapps มาคัดลอกสงครามที่เราทำโดยใช้ gradle build ที่นั่น หลังจากนี้ เราจะเห็นบางอย่างในบันทึก: Deployment of web application archive [tomcat\webapps\webproject.war] has finished in [время] ms เพื่อให้เข้าใจดียิ่งขึ้น เราจะแก้ไขไฟล์ในไดเร็กทอรี Tomcat \conf\tomcat-users.xmlโดยเพิ่มบรรทัดต่อไปนี้:
От Hello World до Spring Web MVC и при чём тут сервлеты - 6
ตอนนี้เรารีสตาร์ทเซิร์ฟเวอร์ (catalina stop, catalina start) และไปที่ที่อยู่ ที่http://127.0.0.1:8080/manager นี่เราจะเห็นเส้นทางของแอปพลิเคชันทั้งหมด เว็บโปรเจ็กต์ของเรามักจะได้รับเส้นทาง /webproject เส้นทางนี้คืออะไร? ข้อกำหนดในบท " 10.1 เว็บแอปพลิเคชันภายในเว็บเซิร์ฟเวอร์ " ระบุว่าเว็บแอปพลิเคชันเชื่อมโยงกับเส้นทางบางอย่างภายในแอปพลิเคชัน (ในกรณีนี้คือ /webproject) คำขอทั้งหมดผ่านเส้นทางนี้จะเชื่อมโยงกับ ServletContext เดียวกัน เส้นทางนี้เรียกอีกอย่างว่าcontextRoot และตาม " 10.2 ความสัมพันธ์กับ ServletContext " คอนเทนเนอร์เซิร์ฟเล็ตเกี่ยวข้องกับเว็บแอปพลิเคชันและ ServletContext แบบหนึ่งต่อหนึ่ง นั่นคือแต่ละเว็บแอปพลิเคชันมี ServletContext ของตัวเอง ServletContextคืออะไร? ตามที่ระบุไว้ในข้อกำหนดServletContextเป็นอ็อบเจ็กต์ที่จัดเตรียมเซิร์ฟเล็ตด้วย "มุมมองของแอปพลิเคชัน " ที่พวกเขากำลังทำงานอยู่ บริบทของเซิร์ฟเล็ต อธิบายไว้ ในรายละเอียดเพิ่มเติมในบทที่ 4 ของข้อกำหนดเฉพาะของ Servlet API น่าแปลกที่ Servlet API ในเวอร์ชัน 3.1 ไม่จำเป็นต้องมี web.xml อีกต่อไป ตัวอย่างเช่น คุณสามารถกำหนดเซิร์ฟเล็ตโดยใช้คำอธิบายประกอบ:
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/app2")
public class App2 extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.setContentType("text/html");
        response.getWriter().println("app2");
    }
}
แนะนำในหัวข้อ: " การสัมภาษณ์ Java EE - JEE Servlet API (คำถามและคำตอบ) " ดังนั้นเราจึงมี Servlet - มีหน้าที่รับผิดชอบในการตอบสนองต่อเว็บไคลเอ็นต์ เรามี ServletContainer ที่รับคำขอจากผู้ใช้ จับคู่เส้นทางที่เข้าถึงด้วยเส้นทางไปยังเซิร์ฟเล็ต และหากพบการจับคู่ ให้ดำเนินการ Servlet ดี. สปริง ครอบครอง สถานที่ใดใน ภาพของโลกนี้

สปริงเว็บ MVC

เยี่ยมเลย เรามีเว็บแอปพลิเคชันแล้ว ตอนนี้เราต้องเชื่อมต่อสปริง เราจะทำเช่นนี้ได้อย่างไร? ขั้นแรก คุณต้องทราบวิธีเชื่อมต่อ Spring กับโปรเจ็กต์ของคุณอย่างถูกต้อง ปรากฎว่าก่อนหน้านี้เป็นไปได้ที่จะทำเช่นนี้ตามเอกสารประกอบของ โครงการ แพลตฟอร์ม Springแต่ตอนนี้ “ แพลตฟอร์มจะสิ้นสุดอายุการใช้งานที่รองรับในวันที่ 9 เมษายน 2019 ” นั่นคือไม่แนะนำให้ทำ ใช้มันเพราะว่า อีกไม่นานก็จะไม่ได้รับการสนับสนุนอีกต่อไป ทางออกเดียวคือ " ผู้ใช้แพลตฟอร์มได้รับการสนับสนุนให้เริ่มใช้การจัดการการพึ่งพาของ Spring Boot " ดังนั้นเรามาดู เอกสาร Spring Boot กันดี กว่า ฉันขอชี้แจงว่าเราไม่ได้ใช้ Spring Boot เอง แต่ใช้เฉพาะการจัดการการพึ่งพาจาก Spring Boot นั่นคือโปรเจ็กต์ Spring Boot สามารถให้ความรู้เกี่ยวกับเวอร์ชันของไลบรารีที่จะใช้ (รวมถึง Spring MVC) ที่นั่นเราจะพบ3.2 การใช้การจัดการการพึ่งพาของ Spring Boot ในการแยกไฟล์ . ตามเอกสารประกอบ ให้เพิ่มสิ่งต่อไปนี้ในสคริปต์การสร้าง:
plugins {
    id 'org.springframework.boot' version '2.0.4.RELEASE' apply false
}
apply plugin: 'io.spring.dependency-management'
และ
dependencyManagement {
    imports {
        mavenBom org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES
    }
}
อย่างที่คุณเห็น เราได้ระบุไว้apply falseเช่น เราไม่ได้ใช้ Spring Boot เอง แต่เราใช้การจัดการการพึ่งพาจากที่นั่น การจัดการการขึ้นต่อกันนี้เรียกอีกอย่างว่า BOM - " รายการวัสดุ " ตอนนี้เราพร้อมที่จะเชื่อมต่อโครงการ Spring Web MVC แล้ว Spring Web MVC เป็นส่วนหนึ่งของ โครงการ Spring Frameworkและเราสนใจในส่วน " Web Servlet " มาเพิ่มการพึ่งพาให้กับสคริปต์การสร้าง: compile 'org.springframework:spring-webmvc'. ดังที่เราเห็น เรากำหนดขอบเขตการคอมไพล์เพราะว่า เว็บเซิร์ฟเวอร์ไม่ได้ให้ Spring แก่เรา โครงการของเราถูกบังคับให้รวมห้องสมุด Spring ไว้ภายในตัวมันเอง ต่อไป เป็นสิ่งสำคัญสำหรับเราที่จะอ่านหัวข้อ " 1.2. DispatcherServlet " ซึ่งมีการกล่าวกันว่าSpring MVCถูกสร้างขึ้นโดยใช้รูปแบบ " Front controller " ซึ่งมีเซิร์ฟเล็ตกลางบางประเภทที่ให้การกำหนดค่าและการมอบหมายไปยังส่วนประกอบอื่น ๆ . ผู้มอบหมายงานสามารถแปลเป็นผู้มอบหมายงานได้ ก่อนอื่นเลย ใน web.xml เราประกาศ:
От Hello World до Spring Web MVC и при чём тут сервлеты - 7
ดังที่เราเห็นแล้วว่านี่คือ Listener ปกติที่กำหนดไว้ในข้อกำหนด Servlet API เพื่อให้แม่นยำยิ่งขึ้น นี่คือ ServletContextListener นั่นคือมันถูกทริกเกอร์ให้เริ่มต้นบริบทของ Servlet สำหรับเว็บแอปพลิเคชันของเรา ถัดไป คุณต้องระบุการตั้งค่าที่จะบอก Spring ว่าการกำหนดค่า xml พิเศษพร้อมการตั้งค่าอยู่ที่ใด:
От Hello World до Spring Web MVC и при чём тут сервлеты - 8
อย่างที่คุณเห็น นี่เป็นเพียงการตั้งค่าปกติที่จัดเก็บไว้ที่ระดับบริบทของเซิร์ฟเล็ต แต่ Spring จะใช้เมื่อเริ่มต้นบริบทของแอปพลิเคชัน ตอนนี้ คุณต้องประกาศโปรแกรมเลือกจ่ายงานเดียวที่กระจายคำขออื่นๆ ทั้งหมด แทนที่จะเป็นเซิร์ฟเล็ตทั้งหมด
От Hello World до Spring Web MVC и при чём тут сервлеты - 9
และไม่มีเวทย์มนตร์ที่นี่ หากเราดู มันคือ HttpServlet โดยที่ Spring ทำหลายๆ อย่างที่ทำให้มันเป็นเฟรมเวิร์ก สิ่งที่เหลืออยู่คือการเชื่อมโยง (แมป) เทมเพลต URL เฉพาะกับเซิร์ฟเล็ต:
От Hello World до Spring Web MVC и при чём тут сервлеты - 10
ทุกอย่างเหมือนกับที่เราเคยทำมาก่อน ตอนนี้เรามาสร้างสิ่งที่เว็บเซิร์ฟเวอร์ของเราควรแสดงกัน ตัวอย่างเช่น เรามาสร้างไดเรกทอรีย่อยของหน้าใน WEB-INF ของเรา และจะมีไฟล์ hello.jsp เนื้อหาอาจเป็นเนื้อหาดั้งเดิมที่สุด ตัวอย่างเช่น ภายในแท็ก html จะมีแท็ก h1 พร้อมข้อความ " Hello World " และอย่าลืมสร้างไฟล์applicationContext.xmlที่เราระบุไว้ก่อนหน้านี้ มาดูตัวอย่างจากเอกสารประกอบของ Spring: " 1.10.3. การตรวจจับคลาสและการลงทะเบียนคำจำกัดความ bean โดยอัตโนมัติ "
От Hello World до Spring Web MVC и при чём тут сервлеты - 11
เพราะ เราเปิดใช้งานการตรวจจับอัตโนมัติด้วยวิธีนี้ ตอนนี้เราสามารถสร้างได้ 2 คลาส (พวกเขาจะถือเป็น Spring Beans เนื่องจากการใช้คำอธิบายประกอบแบบพิเศษของ Spring) ซึ่ง Spring จะสร้างตัวเองและปรับแต่งแอปพลิเคชันของเราด้วยความช่วยเหลือ:
  1. การกำหนดค่าเว็บ เช่น การกำหนดค่าสไตล์ Java:

    @Configuration
    @EnableWebMvc
    public class WebConfig implements WebMvcConfigurer {
        @Override
        public void configureViewResolvers(ViewResolverRegistry registry) {
            registry.jsp("/WEB-INF/pages/", ".jsp");
        }
        @Override
        public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
            configurer.enable();
        }
    }

    ตัวอย่างนี้อธิบายไว้ในเอกสาร Spring Framework: " 1.11. MVC Config "

    ที่นี่เราลงทะเบียน ViewResolver ซึ่งจะช่วยระบุตำแหน่งของหน้า jsp วิธีที่สองช่วยให้แน่ใจว่าเปิดใช้งาน " เซิร์ฟเล็ตเริ่มต้น " แล้ว

    คุณสามารถอ่านเพิ่มเติมเกี่ยวกับเรื่องนี้ได้ที่นี่: " ความต้องการและการใช้ default-servlet-handler คืออะไร "

  2. ตัวควบคุม HelloController สำหรับอธิบายการแมปคำขอไปยัง JSP เฉพาะ

    @Controller
    public class HelloController {
        @GetMapping("/hello")
        public String handle(Model model) {
            return "hello";
        }
    }

    ที่นี่เราได้ใช้คำอธิบายประกอบ @Controller ที่อธิบายไว้ในเอกสารประกอบในบท " 1.4. Annotated Controllers "

ตอนนี้ เมื่อแอปพลิเคชันของเราถูกปรับใช้ เมื่อเราส่งคำขอ/webproject/hello(โดยที่ /webproject เป็นรูทบริบท) DispatcherServlet จะถูกประมวลผลก่อน เขาในฐานะผู้มอบหมายงานหลักจะพิจารณาว่าเรา /* ตรงกับคำขอปัจจุบัน ซึ่งหมายความว่า DispatcherServlet ต้องทำอะไรบางอย่าง จากนั้นมันจะผ่านการแมปทั้งหมดที่พบ จะเห็นว่ามี HelloController พร้อมวิธีจัดการที่แมปกับ /hello และจะดำเนินการดังกล่าว วิธีนี้จะส่งคืนข้อความ "สวัสดี" ViewResolver จะได้รับข้อความนี้ ซึ่งจะบอกเซิร์ฟเวอร์ว่าจะค้นหาไฟล์ jsp ที่ต้องแสดงต่อไคลเอ็นต์ได้จากที่ไหน ดังนั้นในที่สุดลูกค้าก็จะได้รับเพจอันเป็นที่รักอย่างยิ่ง

บทสรุป

หวังว่าบทความจะชัดเจนขึ้นว่าคำว่า “บริบท” ไม่ได้น่ากลัว ข้อมูลจำเพาะนั้นมีประโยชน์มาก และเอกสารก็เป็นเพื่อนของเรา ไม่ใช่ศัตรูของเรา ฉันหวังว่าจะมีความชัดเจนว่า Spring มีพื้นฐานมาจากอะไร เชื่อมต่ออย่างไร และ Servlet API เกี่ยวข้องกับอะไร
ความคิดเห็น
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION