JavaRush /จาวาบล็อก /Random-TH /เว็บแอปพลิเคชันใน Java
Viacheslav
ระดับ

เว็บแอปพลิเคชันใน Java

เผยแพร่ในกลุ่ม
เว็บแอปพลิเคชันใน Java - 1

การแนะนำ

กาลครั้งหนึ่ง Java ได้เสริมความแข็งแกร่งให้กับตำแหน่งของตนเนื่องจากเลือกเว็บแอปพลิเคชันเป็นลำดับความสำคัญ ตั้งแต่วันแรก Java พยายามดิ้นรนเพื่อหาทาง ก่อนอื่นฉันแนะนำแอปเพล็ต นี่เป็นโอกาสมากมายสำหรับนักพัฒนาในการสร้างเนื้อหาแบบไดนามิกบนหน้า HTML แบบคงที่ อย่างไรก็ตาม แอปเพล็ตไม่เป็นไปตามความคาดหวังด้วยเหตุผลหลายประการ เช่น ความปลอดภัย ค่าใช้จ่าย และอื่นๆ จากนั้นนักพัฒนาภาษา Java ได้เสนอทางเลือกอื่น - Servlet API . และกลายเป็นการตัดสินใจที่ถูกต้อง Servlet APIเป็นข้อกำหนดที่ใช้สร้างเว็บแอปพลิเคชัน Java ใด ๆ ไม่ว่าจะเป็นแอปพลิเคชันบนเว็บหรือบริการเว็บที่ส่งคืนข้อมูลตามที่ร้องขอ ดังนั้นเส้นทางสู่การทำความเข้าใจวิธีการทำงานของเว็บแอปพลิเคชัน Java จึงเริ่มต้นด้วยการทำความเข้าใจ Servlet API
เว็บแอปพลิเคชันใน Java - 2

เซิร์ฟเล็ต API

ดังนั้นServlet APIคือสิ่งที่นักพัฒนาภาษาเสนอให้กับนักพัฒนา Java Servlet API เป็นข้อกำหนดที่ควรตอบคำถามหลักของเรา คุณสามารถค้นหาได้ที่นี่: " JSR-000340 JavaTM Servlet 3.1 Final Release for Evalue " บทที่ " 1.1 Servlet คืออะไร " กล่าวว่าเซิร์ฟเล็ตเป็นส่วนประกอบของเว็บที่ใช้เทคโนโลยี Java ที่สร้างเนื้อหาแบบไดนามิก (นั่นคือ เนื้อหา) "แบบ Java" หมายความว่าเซิร์ฟเล็ตเป็นคลาส Java ที่คอมไพล์เป็น bytecode เซิร์ฟเล็ตได้รับการจัดการโดยคอนเทนเนอร์เซิร์ฟเล็ต ซึ่งบางครั้งเรียกว่า Servlet Engine คอนเทนเนอร์เซิร์ฟเล็ตเป็นส่วนขยายของเว็บเซิร์ฟเวอร์ที่มีฟังก์ชันการทำงานของเซิร์ฟเล็ต ในทางกลับกัน เซิร์ฟเล็ตจัดให้มีการโต้ตอบกับไคลเอนต์ในกระบวนทัศน์คำขอ/ตอบกลับ ซึ่งถูกนำไปใช้โดยคอนเทนเนอร์เซิร์ฟเล็ต ในบท " 1.2 Servlet Container คืออะไร " ว่ากันว่าคอนเทนเนอร์ servlet เป็นส่วนหนึ่งของเว็บเซิร์ฟเวอร์หรือแอปพลิเคชันเซิร์ฟเวอร์ที่ให้บริการเครือข่ายซึ่งมีการส่งคำขอและการตอบกลับ คำขอและการตอบกลับที่ใช้ MIME จะถูกสร้างและประมวลผล . นอกจากนี้ คอนเทนเนอร์เซิร์ฟเล็ตจะจัดการวงจรชีวิตของเซิร์ฟเล็ต (เช่น ตัดสินใจว่าจะสร้างเมื่อใด ลบออก ฯลฯ) คอนเทนเนอร์เซิร์ฟเล็ตทั้งหมดต้องรองรับโปรโตคอล HTTP เพื่อรับคำขอและส่งคำตอบ ในที่นี้ฉันต้องการเพิ่มเติมว่า MIME เป็นมาตรฐาน ซึ่งเป็นข้อกำหนดที่บอกว่าข้อมูลควรเข้ารหัสอย่างไรและจัดรูปแบบข้อความเพื่อให้สามารถส่งผ่านอินเทอร์เน็ตได้
เว็บแอปพลิเคชันใน Java - 3

เว็บเซิร์ฟเวอร์

เว็บเซิร์ฟเวอร์คือเซิร์ฟเวอร์ที่ยอมรับคำขอ HTTP จากไคลเอ็นต์ และจัดเตรียมการตอบกลับ HTTP (โดยปกติจะมาพร้อมกับเพจ HTML รูปภาพ ไฟล์ หรือข้อมูลอื่นๆ) ทรัพยากรที่ร้องขอจะถูกระบุโดย URL หนึ่งในเว็บเซิร์ฟเวอร์ยอดนิยมที่รองรับ Servlet API คือApache Tomcat เว็บเซิร์ฟเวอร์ส่วนใหญ่เป็นเครื่องที่ซับซ้อนซึ่งประกอบด้วยส่วนประกอบต่างๆ ซึ่งแต่ละส่วนทำหน้าที่เฉพาะ ตัวอย่างเช่น:
เว็บแอปพลิเคชันใน Java - 4

ขั้วต่อ

— ที่อินพุต เรามีตัวเชื่อมต่อ (เช่น ตัวเชื่อมต่อ) ที่ยอมรับคำขอขาเข้าจากไคลเอนต์ ตัวเชื่อมต่อ HTTP ใน Tomcat ใช้งานโดยใช้ส่วนประกอบ "Coyote" ตัวเชื่อมต่อรับข้อมูลจากไคลเอ็นต์และส่งต่อไปยัง Tomcat Engine Servlet Container - Tomcat Engine ในทางกลับกันจะประมวลผลคำขอที่ได้รับจากไคลเอนต์โดยใช้ส่วนประกอบ "Catalina" ซึ่งเป็นคอนเทนเนอร์เซิร์ฟเล็ต ดูเอกสารประกอบ Tomcat: " ภาพรวมสถาปัตยกรรม " สำหรับรายละเอียดเพิ่มเติม มีเว็บเซิร์ฟเวอร์อื่นๆ ที่รองรับข้อกำหนด Servlet API ตัวอย่างเช่น " Jetty " หรือ " Undertow " สถาปัตยกรรมของพวกเขาคล้ายกัน ดังนั้น เมื่อเข้าใจหลักการทำงานกับเซิร์ฟเล็ตคอนเทนเนอร์หนึ่ง คุณจึงสามารถสลับไปทำงานกับคอนเทนเนอร์เซิร์ฟเล็ตอื่นได้
เว็บแอปพลิเคชันใน Java - 5

แอปพลิเคชันเว็บ

ดังนั้น เพื่อให้เราสามารถรันเว็บแอปพลิเคชันได้ เราจำเป็นต้องมีเว็บเซิร์ฟเวอร์ที่รองรับ Servlet API (นั่นคือ เซิร์ฟเวอร์ที่มีส่วนประกอบส่วนขยายที่ใช้การรองรับ Servlet API สำหรับเว็บเซิร์ฟเวอร์) ดี. เว็บแอปพลิเคชันคืออะไร? ตามบท " 10 Web Applications " ของข้อกำหนดเฉพาะของ Servlet API เว็บแอปพลิเคชันคือชุดของเซิร์ฟเล็ต หน้า HTML คลาส และทรัพยากรอื่น ๆ ที่ประกอบขึ้นเป็นแอปพลิเคชันสุดท้ายบนเว็บเซิร์ฟเวอร์ ตามบท " 10.6 Web Application Archive File " เว็บแอปพลิเคชันสามารถบรรจุใน Web ARchive (ไฟล์เก็บถาวรที่มีนามสกุล WAR) ตามที่ระบุไว้ในหน้า " อภิธานศัพท์-219 ":
เว็บแอปพลิเคชันใน Java - 6
นั่นคือ WAR ถูกสร้างขึ้นแทน JAR เพื่อแสดงว่านี่คือเว็บแอปพลิเคชัน ข้อเท็จจริงที่สำคัญถัดไป: เราต้องมีโครงสร้างไดเร็กทอรีที่แน่นอนในไฟล์เก็บถาวร WAR ของเรา ในข้อกำหนด Servlet API ในบท " 10.5 Directory Structure " บทนี้บอกว่ามีไดเร็กทอรีพิเศษชื่อ "WEB-INF" ไดเร็กทอรีนี้มีความพิเศษตรงที่ไคลเอ็นต์ไม่สามารถมองเห็นได้ และไม่ได้แสดงโดยตรง แต่โค้ดเซิร์ฟเล็ตสามารถเข้าถึงได้ นอกจากนี้ยังระบุด้วยว่าไดเร็กทอรี WEB-INF สามารถประกอบด้วยอะไร:
เว็บแอปพลิเคชันใน Java - 7
จากรายการทั้งหมดนี้ ตอนนี้เราไม่ทราบและไม่เข้าใจรายการเกี่ยวกับ ไฟล์ web.xml บางไฟล์ ที่เรียกว่าDescriptor การใช้งาน มันคืออะไร? บทที่ " 14. Deployment Descriptor " เน้นไปที่ Descriptor การนำไปใช้งาน กล่าวโดยสรุปตัวอธิบายการปรับใช้คือไฟล์ xml ที่อธิบายวิธีการปรับใช้ (นั่นคือ รัน) เว็บแอปพลิเคชันของเราบนเว็บเซิร์ฟเวอร์ ตัวอย่างเช่น ตัวอธิบายการปรับใช้จะระบุว่าควรใช้ URL ใดในการเข้าถึงแอปพลิเคชันของเรา การตั้งค่าความปลอดภัยที่เกี่ยวข้องกับแอปพลิเคชันของเรา ฯลฯ จะถูกระบุ บท " 14.2 กฎสำหรับการประมวลผลการปรับใช้ " บอกว่า web.xml จะได้รับการตรวจสอบความถูกต้องของสคีมาก่อนที่แอปพลิเคชันของเราจะได้รับการกำหนดค่าและเปิดใช้งาน (นั่นคือ จะมีการตรวจสอบว่าเนื้อหาของ web.xml ถูกเขียนอย่างถูกต้องตามสคีมา) . และในบท " 14.3 Deployment Descriptor " ระบุว่ามีไดอะแกรมอยู่ที่นี่ http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd ถ้าเราดูเนื้อหาของไฟล์ เราจะเห็น:
เว็บแอปพลิเคชันใน Java - 8
สคีมาใช้สำหรับไฟล์ XML คืออะไร สคีมาระบุวิธีการกรอกเอกสาร XML อย่างถูกต้อง: องค์ประกอบใดที่สามารถใช้ได้, ประเภทข้อมูลใดที่สามารถระบุในองค์ประกอบ, ลำดับที่องค์ประกอบควรจะไป, องค์ประกอบใดที่จำเป็น ฯลฯ คุณสามารถเปรียบเทียบสคีมาของเอกสาร XML กับอินเทอร์เฟซใน Java ได้ เนื่องจากสคีมาใน Java ยังระบุวิธีการเขียนคลาสที่ตรงตามอินเทอร์เฟซที่กำหนด (นั่นคือ การนำอินเทอร์เฟซที่กำหนดไปใช้) ควรเขียนอย่างไร ดังนั้นเราจึงมีความรู้ที่เป็นความลับและพร้อมที่จะสร้างเว็บแอปพลิเคชันแรกของเรา!
เว็บแอปพลิเคชันใน Java - 9

การสร้างเว็บแอปพลิเคชัน

เป็นเรื่องยากที่จะจินตนาการถึงการทำงานกับแอปพลิเคชัน Java สมัยใหม่โดยไม่ต้องใช้ระบบการสร้างโปรเจ็กต์อัตโนมัติ ระบบที่ได้รับความนิยมมากที่สุด ได้แก่Maven และ Gradle เราจะใช้ Gradle สำหรับการตรวจสอบนี้ การติดตั้ง Gradle อธิบายไว้ในเว็บไซต์อย่างเป็นทางการ . ในการสร้างแอปพลิเคชันใหม่ เราจำเป็นต้องมีปลั๊กอินที่สร้างไว้ใน Gradle: " Build Init Plugin " ในการสร้างแอปพลิเคชัน Java คุณต้องรันคำสั่งต่อไปนี้: gradle init --type java-application
เว็บแอปพลิเคชันใน Java - 10
หลังจากสร้างโปรเจ็กต์ แล้วเราจะต้องแก้ไข ไฟล์ build.gradle นี่คือสิ่งที่เรียกว่า Build Script (สำหรับรายละเอียดเพิ่มเติม โปรดดูเอกสารประกอบของ Gradle: " การเขียนสคริปต์ Build ") ไฟล์นี้อธิบายวิธีการประกอบโปรเจ็กต์และลักษณะอื่นๆ ของการทำงานกับโปรเจ็กต์ Java บล็อกปลั๊กอินอธิบายว่า " ปลั๊กอิน Gradle " ใดที่ควรใช้สำหรับโครงการ Gradle ปัจจุบัน ปลั๊กอินขยายขีดความสามารถของโครงการของเรา ตัวอย่างเช่น ปลั๊กอินเริ่มต้นคือ " java " ปลั๊กอินนี้จะใช้เสมอหากเราต้องการการสนับสนุน Java แต่เราไม่ต้องการ ปลั๊กอิน “ application ” เพราะ... คำอธิบายระบุว่าใช้เพื่อสร้าง "แอปพลิเคชัน JVM ที่ปฏิบัติการได้" เช่น ใช้งานแอปพลิเคชัน JVM เราจำเป็นต้องสร้างเว็บแอปพลิเคชันในรูปแบบของไฟล์เก็บถาวร WAR และหากเรามองหาคำว่า WAR ในเอกสารประกอบของ Gradle เราจะพบ “ War Plugin ” ดังนั้นเราจะระบุปลั๊กอินดังต่อไปนี้:
plugins {
    id 'java'
    id 'war'
}
นอกจากนี้ใน " War Plugin Default Settings " ว่ากันว่าไดเร็กทอรีที่มีเนื้อหาทั้งหมดของเว็บแอปพลิเคชันควรเป็น "src/main/webapp" ควรมีไดเร็กทอรี WEB-INF เดียวกันกับที่ web.xml ควรเป็น ตั้งอยู่. มาสร้างไฟล์ดังกล่าวกัน เราจะกรอกข้อมูลในภายหลังเล็กน้อยเพราะ... เรายังไม่มีข้อมูลเพียงพอสำหรับเรื่องนี้ ในบล็อก "การขึ้นต่อกัน" เราระบุการขึ้นต่อกันของโปรเจ็กต์ของเรา นั่นคือ ไลบรารี/เฟรมเวิร์กเหล่านั้น หากปราศจากนั้น แอปพลิเคชันของเราจะไม่สามารถทำงานได้ ในกรณีนี้ เรากำลังเขียนเว็บแอปพลิเคชัน ซึ่งหมายความว่าเราจะไม่สามารถทำงานได้หากไม่มี Servlet API:
dependencies {
    providedCompile 'javax.servlet:javax.servlet-api:3.1.0'
    testCompile 'junit:junit:4.12'
}
ProvideCompile หมายความว่าไม่จำเป็นต้องรวมการขึ้นต่อกันในไฟล์เก็บถาวร WAR ของเว็บแอปพลิเคชันของเรา: จำเป็นสำหรับการคอมไพล์เท่านั้น และเมื่อดำเนินการแล้ว บุคคลอื่นจะเป็นผู้จัดหาการพึ่งพานี้ (นั่นคือ เว็บเซิร์ฟเวอร์) เราทิ้งข้อมูลสคริปต์การสร้างเกี่ยวกับที่เก็บการพึ่งพาที่เราต้องการใช้ - การขึ้นต่อกันที่ระบุทั้งหมดจะถูกดาวน์โหลดจากมัน:
repositories {
    jcenter()
}
เราลบทุกอย่างออกจากไฟล์สคริปต์บิลด์ ตอนนี้เรามาแก้ไขคลาส src\main\java\App.java กันดีกว่า มาสร้างเซิร์ฟเล็ตกันดีกว่า ข้อกำหนดของ Servlet API ในบท " บทที่ 2 Servlet Interface " ระบุว่า Servlet Interface มีการใช้งานพื้นฐานของ HttpServletซึ่งควรจะเพียงพอในกรณีส่วนใหญ่ และนักพัฒนาเพียงแค่ต้องสืบทอดจากมัน และในบท " 2.1.1 วิธีการจัดการคำขอเฉพาะ HTTP " วิธีการหลักที่ประมวลผลคำขอขาเข้าจะถูกระบุ ดังนั้น เรามาเขียนคลาส App.java ใหม่กัน:
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.io.IOException;

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

    public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
 		// https://www.oracle.com/technetwork/java/servlet-142430.html
 		PrintWriter out = resp.getWriter();
 		out.println(this.getGreeting());
 		out.close();
 	}
}
ดูเหมือนว่าเราจะมีทุกอย่างพร้อมแล้ว สิ่งที่เหลืออยู่คือการเขียนตัวอธิบายการใช้งานอย่างถูกต้อง จากแผนภาพ ให้คัดลอกข้อความต่อไปนี้ลงใน web.xml:
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="..."
      version="3.1">
      ...
</web-app>
และเส้นทางไปยังสคีมาที่ระบุไว้ด้วย: http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd ตอนนี้เรามาดูตัวอย่างว่า web.xml ควรมีลักษณะอย่างไรในข้อกำหนด Servlet API ตัวอย่างนี้มีให้ในบท " 14.5.1 ตัวอย่างพื้นฐาน " ลองรวมสิ่งที่ระบุไว้ในแผนภาพกับตัวอย่างที่ระบุในข้อกำหนด เราได้รับสิ่งต่อไปนี้:
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
      http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
      version="3.1">
      <display-name>A Simple Web Application</display-name>
      <servlet>
		<servlet-name>app</servlet-name>
		<servlet-class>App</servlet-class>
	  </servlet>
	  <servlet-mapping>
		<servlet-name>app</servlet-name>
		<url-pattern>/app</url-pattern>
	  </servlet-mapping>
</web-app>
อย่างที่คุณเห็น เราใช้สคีมาและ schemaLocation ที่ระบุไว้ก่อนหน้านี้ และคำอธิบายขององค์ประกอบเองก็นำมาจากตัวอย่างจากบทที่ 14.5.1 หากเราทำทุกอย่างถูกต้อง เราจะรันงาน gradle war โดยไม่มีข้อผิดพลาด:
เว็บแอปพลิเคชันใน Java - 11
เว็บแอปพลิเคชันใน Java - 12

การเปิดตัวแอปพลิเคชันเว็บ

เว็บแอปพลิเคชั่นเปิดตัวอย่างไร? มาจัดการกับตัวเลือกที่ซับซ้อนกว่านี้ก่อน ก่อนหน้านี้เราบอกว่ามีเว็บเซิร์ฟเวอร์ Apache Tomcat ที่รองรับ Servlet API ซึ่งหมายความว่าเราสามารถปรับใช้คลังข้อมูลสงครามที่รวบรวมไว้ของเราได้ (พวกเขายังพูดว่า "ปรับใช้") บนเซิร์ฟเวอร์นี้ ในหน้า " ดาวน์โหลด Tomcat " ให้ดาวน์โหลดจากส่วน "Binary Distributions" ประเภทการจัดส่ง "Core" ในรูปแบบ zip และคลายไฟล์ที่ดาวน์โหลดมาลงในไดเร็กทอรีบางตัว เช่น ใน C:\apache-tomcat-9.0.14 ก่อนที่จะเริ่มเซิร์ฟเวอร์ เรามาเปิดไฟล์เพื่อแก้ไขconf\tomcat-users.xmlและเพิ่มบรรทัดต่อไปนี้: <user username="tomcat" password="tomcat" roles="tomcat,manager-gui,admin-gui"/> ตอนนี้บนบรรทัดคำสั่ง ไปที่ไดเร็กทอรี bin และดำเนินการcatalina.bat start. ตามค่าเริ่มต้น คอนโซลเซิร์ฟเวอร์จะพร้อมใช้งานhttp://localhost:8080/managerที่ ข้อมูลเข้าสู่ระบบและรหัสผ่านเหมือนกันกับที่เราระบุไว้ใน tomcat-users.xml Tomcat มีไดเรกทอรี "webapps" ซึ่งมีเว็บแอปพลิเคชัน หากเราต้องการวางกำลังของเราเอง เราต้องคัดลอกเอกสารสงครามของเราที่นั่น เมื่อก่อนหน้านี้เรารันคำสั่ง gradle war \build\libs\ไฟล์เก็บถาวร war จะถูกสร้างขึ้นในไดเร็กทอรี นี่คือสิ่งที่เราต้องคัดลอก หลังจากคัดลอกแล้ว ให้รีเฟรชหน้าhttp://localhost:8080/managerและดู:
เว็บแอปพลิเคชันใน Java - 13
เมื่อเสร็จแล้วhttp://localhost:8080/javaweb/appเราจะหันมาใช้เซิร์ฟเล็ตของเราเพราะ ก่อนหน้านี้เรา "แมป" (นั่นคือ แมป) คำขอ /app ไปยัง App servlet มีวิธีที่เร็วกว่าในการตรวจสอบว่าแอปพลิเคชันทำงานอย่างไร และระบบการประกอบก็ช่วยเราในเรื่องนี้อีกครั้ง ในสคริปต์การสร้างของโปรเจ็กต์ Gradle ของเรา เราสามารถเพิ่มปลั๊กอินใหม่ " Gretty " ลงในส่วนปลั๊กอินได้ id "org.gretty" version "2.3.1" และตอนนี้เราสามารถดำเนินการ gradle เพื่อรันแอปพลิเคชันของเราได้:gradle appRun
เว็บแอปพลิเคชันใน Java - 14
ดู " เพิ่มปลั๊กอิน gretty และเรียกใช้แอป " เพื่อดูรายละเอียด
เว็บแอปพลิเคชันใน Java - 15

Spring และ Servlet API

เซิร์ฟเล็ตเป็นพื้นฐานของทุกสิ่ง และแม้แต่ Spring Framework ที่ได้รับความนิยมในขณะนี้ก็ไม่มีอะไรมากไปกว่าส่วนเสริมของ Servlet API เริ่มต้นด้วยSpring Frameworkเป็นการพึ่งพาใหม่สำหรับโครงการของเรา ดังนั้น มาเพิ่มลงในสคริปต์การสร้างในบล็อกการอ้างอิง: compile 'org.springframework:spring-webmvc:5.1.3.RELEASE' ในเอกสาร Spring Framework มีบท " 1.1. DispatcherServlet " มันบอกว่า Spring Framework ถูกสร้างขึ้นบนรูปแบบ "ตัวควบคุมด้านหน้า" - นี่คือเมื่อมีเซิร์ฟเล็ตกลางที่เรียกว่า " DispatcherServlet " คำขอทั้งหมดมาที่เซิร์ฟเล็ตนี้ และจะมอบหมายการโทรไปยังส่วนประกอบที่จำเป็น คุณเห็นไหมว่าที่นี่ยังมีเซิร์ฟเล็ตอยู่ คุณต้องเพิ่ม Listener ให้กับ Descriptor การนำไปใช้งาน:
<listener>
	&ltlistener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
นี่คือ Listener เหตุการณ์บริบทเซิร์ฟเล็ต นั่นคือเมื่อ Servlet Context เริ่มต้น บริบท Spring (WebApplicationContext) ก็เริ่มทำงานเช่นกัน บริบทของเซิร์ฟเล็ตคืออะไร? มีการอธิบายไว้ในข้อกำหนด Servle API ในบท " บทที่ 4 บริบทของ Servlet " บริบทเซิร์ฟเล็ตคือ "มุมมอง" ของเซิร์ฟเล็ตของเว็บแอปพลิเคชันที่เซิร์ฟเล็ตกำลังทำงานอยู่ แต่ละเว็บแอปพลิเคชันมีบริบท Servlet ของตัวเอง ถัดไป เพื่อเปิดใช้งาน Spring Framework คุณต้องระบุ context-param - พารามิเตอร์การเริ่มต้นสำหรับบริบทเซิร์ฟเล็ต
<context-param>
	<param-name>contextConfigLocation</param-name>
	<param-value>/WEB-INF/app-context.xml</param-value>
</context-param>
และ คำจำกัดความ DispatcherServlet จะทำให้การกำหนดค่าเสร็จสมบูรณ์ :
<servlet>
	<servlet-name>app</servlet-name>
	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
	<init-param>
		<param-name>contextConfigLocation</param-name>
 		<param-value></param-value>
	</init-param>
	<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
	<servlet-name>app</servlet-name>
	<url-pattern>/</url-pattern>
</servlet-mapping>
และตอนนี้เราเพียงแค่ต้องกรอกไฟล์ที่ระบุใน contextConfigLocation วิธีการทำเช่นนี้ได้อธิบายไว้ในเอกสาร Spring Framework ในบท "1.3.1. Declaration":
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <context:component-scan base-package="ru.javarush.javaweb"/>
    <mvc:annotation-driven/>
</beans>
สิ่งสำคัญที่นี่ไม่เพียงแต่เพื่อระบุว่าแพ็คเกจใดที่จะสแกนเท่านั้น แต่ยังต้องการให้เราต้องการคำอธิบายประกอบด้วย นั่นคือเพื่อควบคุมคำอธิบายประกอบว่า Spring จะทำงานอย่างไร สิ่งที่เหลืออยู่คือการสร้างแพ็คเกจ ru.javarush.javaweb และวางคลาส Spring controller ลงไป:
package ru.javarush.javaweb;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class SpringController {

    @GetMapping("/app")
    @ResponseBody
    public String getGreeting() {
        return "Hello world.";
    }
}
ตอนนี้รัน gradle appRun และไปที่ที่อยู่http://127.0.0.1:8080/javaweb/appเราก็จะได้ Hello World เหมือนเดิม อย่างที่คุณเห็น Spring Framework มีความเชื่อมโยงอย่างใกล้ชิดกับ Servlet API และใช้เพื่อทำงานด้านบน
เว็บแอปพลิเคชันใน Java - 16

คำอธิบายประกอบ

ดังที่เราได้เห็นแล้วว่าคำอธิบายประกอบมีความสะดวก และเราไม่ใช่คนเดียวที่คิดเช่นนั้น ดังนั้นในข้อกำหนด Servlet API เริ่มต้นด้วยเวอร์ชัน 3.0 บท “ บทที่ 8 คำอธิบายประกอบและความสามารถในการเสียบปลั๊ก ” จึงปรากฏขึ้น ซึ่งระบุว่าคอนเทนเนอร์เซิร์ฟเล็ตต้องรองรับความสามารถในการระบุสิ่งที่ระบุไว้ก่อนหน้านี้ใน Deployment Descriptor ผ่านคำอธิบายประกอบ ดังนั้น web.xml จึงสามารถลบออกจากโปรเจ็กต์ได้อย่างสมบูรณ์ และเหนือคลาสเซิร์ฟเล็ต คุณสามารถระบุ คำอธิบายประกอบ @WebServletและระบุพาธที่จะแมปเซิร์ฟเล็ตไป ทุกอย่างดูเหมือนชัดเจนที่นี่ แต่ถ้าเราเชื่อมต่อ Spring เข้ากับโปรเจ็กต์ซึ่งต้องการการตั้งค่าที่ซับซ้อนกว่านี้ล่ะ ที่นี่ทุกอย่างซับซ้อนขึ้นเล็กน้อย อันดับแรก เอกสารประกอบของ Spring บอกว่าในการกำหนดค่า Spring โดยไม่มี web.xml คุณต้องใช้คลาสของคุณเองที่จะใช้ WebApplicationInitializer สำหรับรายละเอียดเพิ่มเติม ดูบท " 1.1. DispatcherServlet " ปรากฎว่านี่คือคลาส Spring Servlet API ใช้ที่นี่อย่างไร ที่จริงแล้วServletContainerInitializer ถูกเพิ่มใน Servlet API 3.0 การใช้กลไกพิเศษใน Java (เรียกว่าSPI ) Spring จะระบุตัวเริ่มต้นคอนเทนเนอร์เซิร์ฟเล็ตที่เรียกSpringServletContainerInitializerว่า ในทางกลับกัน จะค้นหาการใช้งาน WebApplicationInitializer และเรียกวิธีการที่จำเป็นและดำเนินการตั้งค่าที่จำเป็น ดู " วิธีที่คอนเทนเนอร์เซิร์ฟเล็ตค้นหาการใช้งาน WebApplicationInitializer " สำหรับรายละเอียดเพิ่มเติม การตั้งค่าข้างต้นสามารถทำได้ดังนี้:
package ru.javarush.javaweb.config;

import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;

public class AppInitializer implements WebApplicationInitializer {
    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
        // регистрируем конфигурацию созданую высше
        ctx.register(AppConfig.class);
        // добавляем в контекст слушателя с нашей конфигурацией
        servletContext.addListener(new ContextLoaderListener(ctx));

        ctx.setServletContext(servletContext);

        // настраиваем маппинг Dispatcher Servlet-а
        ServletRegistration.Dynamic servlet =
                servletContext.addServlet("dispatcher", new DispatcherServlet(ctx));
        servlet.addMapping("/");
        servlet.setLoadOnStartup(1);
    }
}
ตอนนี้ เมื่อใช้ " การกำหนดค่าตาม Java " เราจะระบุว่าแพ็คเกจใดที่จะสแกน + เปิดใช้งานคำอธิบายประกอบ:
package ru.javarush.javaweb.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "ru.javarush.javaweb.controllers")
public class AppConfig {
}
และ SpringController เองก็ถูกย้ายไปที่ru.javarush.javaweb.controllersดังนั้นเมื่อทำการสแกน การกำหนดค่าจะไม่พบตัวเอง แต่จะมองหาเฉพาะตัวควบคุมเท่านั้น
เว็บแอปพลิเคชันใน Java - 17

สรุป

ฉันหวังว่าภาพรวมนี้จะช่วยให้กระจ่างเกี่ยวกับวิธีการทำงานของเว็บแอปพลิเคชันใน Java นี่เป็นเพียงส่วนเล็กๆ ของภูเขาน้ำแข็ง แต่ถ้าไม่เข้าใจพื้นฐาน ก็เป็นเรื่องยากที่จะเข้าใจว่าเทคโนโลยีที่ใช้รากฐานนี้ทำงานอย่างไร Servlet API เป็นส่วนสำคัญของเว็บแอปพลิเคชัน Java และเราได้ดูว่าเฟรมเวิร์กอื่นๆ เข้ากับมันอย่างไร หากต้องการดำเนินการต่อ คุณสามารถดูเอกสารต่อไปนี้: #เวียเชสลาฟ
ความคิดเห็น
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION