Dispatcher Servlet ในฤดูใบไม้ผลิคืออะไร


195

ในภาพนี้ (ที่ฉันได้จากที่นี่ ), HTTPคำขอส่งบางสิ่งไปยังDispatcher Servlet

ป้อนคำอธิบายรูปภาพที่นี่

คำถามของฉันคือDispatcher Servletทำอะไรได้บ้าง

มันเหมือนกับการดึงข้อมูลจากหน้าเว็บแล้วส่งไปยังคอนโทรลเลอร์หรือไม่?

คำตอบ:


202

งานของDispatcherServletคือการใช้ URI ที่เข้ามาและค้นหาการรวมกันที่เหมาะสมของตัวจัดการ (โดยทั่วไปวิธีการบนคอนโทรลเลอร์คลาส ) และมุมมอง (โดยทั่วไปคือ JSP) ที่รวมกันเป็นรูปแบบของเพจหรือทรัพยากรที่ควรจะอยู่ในตำแหน่งนั้น

ฉันอาจจะมี

  • ไฟล์ /WEB-INF/jsp/pages/Home.jsp
  • และวิธีการในชั้นเรียน

    @RequestMapping(value="/pages/Home.html")
    private ModelMap buildHome() {
        return somestuff;
    }

เซิร์ฟเล็ตรีบเป็นบิตที่ว่า "รู้" เพื่อเรียกวิธีการว่าเมื่อเบราว์เซอร์ร้องขอหน้าและจะรวมผลการดำเนินงานที่มีไฟล์ JSP การจับคู่เพื่อให้เอกสาร HTML

วิธีการทำให้สำเร็จนี้แตกต่างกันอย่างมากกับการกำหนดค่าและรุ่นฤดูใบไม้ผลิ

ไม่มีเหตุผลที่ผลลัพธ์จะต้องเป็นหน้าเว็บ มันสามารถทำสิ่งเดียวกันเพื่อค้นหาจุดสิ้นสุดRMIจัดการคำขอSOAPทุกสิ่งที่สามารถเข้าสู่เซิร์ฟเล็ตได้


4
เยี่ยมมากตอนนี้เป็นคำถามที่ว่า DispatcherServlet ระบุชื่อคลาสและชื่อเมธอดด้วยเช่นกัน คุณสามารถแสดงตัวอย่างของการกำหนดค่าที่ฉันมีสองคลาสและชื่อเมธอดสองวิธีและวิธีที่ DispatcherServlet จับการร้องขอที่ถูกต้อง
Kevin

10
จริง ๆ แล้วมันจะสแกนคลาสพา ธ เมื่อเริ่มต้นคำอธิบายประกอบนั้นและทำการแมปของ "/pages/Home.html" ไปที่เมธอด Class + หากคุณมีสองวิธีที่ทั้งสองมี "/pages/Home.html" โดยไม่มีข้อ จำกัด อื่น ๆ ในการเพิ่มความคิดเห็นนั่นจะเป็นข้อผิดพลาดและจะโยนข้อยกเว้นให้คุณ คุณสามารถโยงมันเข้ากับ XML ได้ถ้าคุณอายุมาก
Affe

2
เราจำเป็นต้องมีDispatcher Servletไฟล์ xml เมื่อใช้คำอธิบายประกอบ@RestControllerหรือไม่
viper

1
@viper ใน web.xml เราจำเป็นต้องกำหนดค่า servlet dispatcher เสมอถึงแม้ว่าคุณจะใช้คำอธิบายประกอบหรือการกำหนดค่า XML
Mahender Reddy Yasa

มี servlet ประเภทอื่นหรือไม่?
Minh Nghĩa

72

ใน Spring MVC คำขอที่เข้ามาทั้งหมดจะผ่านเซิร์ฟเล็ตเดียว servlet นี้ - DispatcherServlet- เป็นตัวควบคุมด้านหน้า Front controller เป็นรูปแบบการออกแบบทั่วไปในการพัฒนาเว็บแอพพลิเคชั่น ในกรณีนี้เซิร์ฟเล็ตเดียวได้รับคำร้องขอทั้งหมดและโอนไปยังคอมโพเนนต์อื่นทั้งหมดของแอ็พพลิเคชัน

ภารกิจของการDispatcherServletส่งคำร้องขอไปยังคอนโทรลเลอร์ Spring MVC ที่ระบุ

โดยปกติเรามีตัวควบคุมจำนวนมากและDispatcherServletอ้างอิงถึงตัวแมปต่อไปนี้เพื่อกำหนดตัวควบคุมเป้าหมาย:

หากไม่มีการกำหนดค่าใด ๆ การDispatcherServletใช้BeanNameUrlHandlerMappingและDefaultAnnotationHandlerMappingตามค่าเริ่มต้น

เมื่อมีการระบุตัวควบคุมเป้าหมายDispatcherServletส่งคำขอไปยังมัน ตัวควบคุมจะทำงานบางอย่างตามคำขอ (หรือมอบให้กับวัตถุอื่น) และส่งคืนกลับไปDispatcherServletพร้อมกับรุ่นและชื่อของมุมมอง

ชื่อของมุมมองเป็นชื่อโลจิคัลเท่านั้น ชื่อโลจิคัลนี้จะถูกใช้เพื่อค้นหามุมมองจริง (เพื่อหลีกเลี่ยงการเชื่อมต่อกับคอนโทรลเลอร์และมุมมองเฉพาะ) จากนั้นDispatcherServletอ้างถึงViewResolverและแม็พชื่อโลจิคัลของมุมมองกับการนำไปใช้งานเฉพาะของมุมมอง

การใช้งานที่เป็นไปได้บางอย่างของViewResolverคือ:

เมื่อDispatcherServletกำหนดมุมมองที่จะแสดงผลลัพธ์มันจะถูกแสดงผลเป็นการตอบสนอง

ในที่สุดการDispatcherServletส่งคืนResponseวัตถุกลับไปยังลูกค้า


47

DispatcherServletคือการดำเนินการในฤดูใบไม้ผลิ MVC ของรูปแบบการควบคุมด้านหน้า

ดูรายละเอียดในเอกสารฤดูใบไม้ผลิที่นี่

โดยพื้นฐานแล้วมันเป็นเซิร์ฟเล็ตที่รับคำร้องขอขาเข้าและมอบหมายการประมวลผลคำร้องขอนั้นให้กับหนึ่งในจำนวนของตัวจัดการการแมปที่เฉพาะในการDispatcherServletกำหนดค่า


เป็นเหมือนกิจกรรมใน Flex หรือไม่ที่ฉันรับการจัดส่งกิจกรรมจาก MXML หนึ่งไปยังอีกหรือไปยังเซิร์ฟเวอร์ ฉันสามารถมี DispatcherServlet ได้มากกว่าหนึ่งรายการในการสมัครของฉันหรือไม่ ทำแต่ละคลาสไฟล์มี DispatcherServlet แยกกัน
Kevin

โดยปกติจะมีเพียงหนึ่งตัวควบคุมด้านหน้า สิ่งนี้ไม่คำนึงถึงรุ่นและมุมมองที่คุณมี มันเป็นเพียงการนำรูปแบบเฉพาะและมุมมองเข้าด้วยกัน
BalusC

2
@Theband: คุณสามารถมีได้หลายDispatcherServletsอย่างถ้าสถาปัตยกรรมของคุณมีเหตุผลมากกว่านั้น แต่โดยทั่วไปแล้วก็ไม่มีเหตุผล
skaffman

47

ฉันรู้ว่าคำถามนี้ถูกทำเครื่องหมายว่าแก้ไขแล้ว แต่ฉันต้องการเพิ่มภาพใหม่ที่อธิบายรูปแบบนี้โดยละเอียด (แหล่งที่มา: สปริงแอ็คชั่น 4):

ป้อนคำอธิบายรูปภาพที่นี่

คำอธิบาย

เมื่อคำขอออกจากเบราว์เซอร์(1)จะมีข้อมูลเกี่ยวกับสิ่งที่ผู้ใช้ร้องขอ อย่างน้อยที่สุดคำขอจะถือ URL ที่ขอ แต่อาจมีข้อมูลเพิ่มเติมเช่นข้อมูลที่ส่งในแบบฟอร์มโดยผู้ใช้

จุดแรกในการเดินทางของคำขอคือที่ Spring's DispatcherServlet เช่นเดียวกับเว็บเฟรมเวิร์กที่ใช้จาวาส่วนใหญ่ Spring MVC funnels ร้องขอผ่าน servlet คอนโทรลเลอร์ด้านหน้าเดียว front controller เป็นรูปแบบเว็บแอ็พพลิเคชันทั่วไปที่เซิร์ฟเล็ตเดียวมอบหมายความรับผิดชอบสำหรับการร้องขอไปยังคอมโพเนนต์อื่นของแอ็พพลิเคชันเพื่อประมวลผลตามจริง ในกรณีของ Spring MVC DispatcherServlet เป็นตัวควบคุมด้านหน้า งานของ DispatcherServlet คือการส่งคำขอไปยังตัวควบคุม Spring MVC คอนโทรลเลอร์เป็นส่วนประกอบสปริงที่ประมวลผลคำขอ แต่แอปพลิเคชันทั่วไปอาจมีคอนโทรลเลอร์หลายตัวและ DispatcherServlet ต้องการความช่วยเหลือในการตัดสินใจว่าคอนโทรลเลอร์ใดที่จะส่งคำขอไป ดังนั้น DispatcherServlet ให้คำปรึกษาการแมปตัวจัดการอย่างน้อยหนึ่งรายการ (2)เพื่อกำหนดว่าจุดหยุดต่อไปของคำขอจะเป็นอย่างไร การแม็พตัวจัดการให้ความสนใจเป็นพิเศษกับ URL ที่ดำเนินการโดยคำร้องขอเมื่อทำการตัดสินใจ เมื่อเลือกคอนโทรลเลอร์ที่เหมาะสมแล้ว DispatcherServlet จะส่งคำร้องขอไปยังตัวควบคุมที่เลือก (3). ที่ตัวควบคุมคำขอจะลดอัตราการส่งข้อมูล (ข้อมูลที่ส่งโดยผู้ใช้) และรออย่างอดทนในขณะที่ตัวควบคุมประมวลผลข้อมูลนั้น (ที่จริงแล้วคอนโทรลเลอร์ที่ได้รับการออกแบบมาอย่างดีนั้นจะประมวลผลเพียงเล็กน้อยหรือไม่มีเลยและแทนที่จะมอบหมายความรับผิดชอบสำหรับตรรกะทางธุรกิจให้กับออบเจกต์บริการหนึ่งตัวหรือมากกว่า) ตรรกะที่ดำเนินการโดยคอนโทรลเลอร์มักส่งผลให้ข้อมูลบางอย่าง ผู้ใช้และแสดงในเบราว์เซอร์ ข้อมูลนี้เรียกว่าแบบจำลอง แต่การส่งข้อมูลดิบกลับไปยังผู้ใช้นั้นไม่เพียงพอมันต้องมีการจัดรูปแบบในรูปแบบที่ใช้งานง่ายซึ่งโดยทั่วไปคือ HTML สำหรับสิ่งนั้นข้อมูลจะต้องถูกกำหนดให้กับมุมมองโดยทั่วไปคือ JavaServer Page (JSP) หนึ่งในสิ่งสุดท้ายที่ผู้ควบคุมทำคือทำแพ็กเกจข้อมูลโมเดลและระบุชื่อของมุมมองที่ควรแสดงผล จากนั้นจะส่งคำขอพร้อมกับรุ่นและชื่อมุมมองกลับไปที่ DispatcherServlet(4)(4)เพื่อให้คอนโทรลเลอร์ไม่ได้เชื่อมโยงกับมุมมองเฉพาะชื่อมุมมองที่ส่งกลับไปยัง DispatcherServlet จะไม่ระบุ JSP เฉพาะโดยตรง ไม่จำเป็นแม้แต่แนะนำว่ามุมมองเป็น JSP แต่จะมีชื่อโลจิคัลที่จะใช้เพื่อค้นหามุมมองจริงที่จะสร้างผลลัพธ์เท่านั้น DispatcherServlet ให้คำปรึกษาตัวแก้ไขมุมมอง(5)เพื่อจับคู่ชื่อมุมมองแบบลอจิคัลกับการปรับใช้มุมมองแบบพิเศษซึ่งอาจหรืออาจไม่ใช่ JSP เมื่อ DispatcherServlet รู้ว่ามุมมองใดที่จะทำให้เกิดผลลัพธ์งานของคำร้องขอใกล้จะหมด จุดแวะชมสุดท้ายคือการใช้งานมุมมองซึ่งโดยปกติจะเป็น JSP ซึ่งส่งข้อมูลโมเดล ในที่สุดงานของคำขอเสร็จแล้ว มุมมองที่จะใช้ข้อมูลรูปแบบที่จะทำให้การส่งออกที่จะได้รับการดำเนินการกลับไปยังลูกค้าโดย (not- ที่ทำงานหนัก) วัตถุการตอบสนอง(7) (6)


ฉันมีคำถามว่ามันเลือกมุมมองอย่างไรในกรณีที่ส่งคืนออบเจ็กต์ JSON ที่เราเห็นในเบราว์เซอร์มันกลับไปที่ URI เดียวกันหรือไม่หากไม่มีการเลือกมุมมองแบบลอจิคัล?
Nesrin

1
@Nesrin มีอายุมากแล้วตั้งแต่คุณถาม แต่นี่เป็นคำตอบ: คุณใส่คำอธิบายประกอบพิเศษเหนือ@Controllerวิธีที่เรียกว่า@ResponseBodyระบุว่าการตอบกลับที่ส่งกลับควรเขียนโดยตรงบนเนื้อหาการตอบสนอง HTTP ไม่ควรอยู่ในรูปแบบหรือแก้ไขตามที่เห็น .
แดชบอร์ด

6

เราสามารถพูดได้เช่น DispatcherServletดูแลทุกอย่างใน Spring MVC

ที่เริ่มต้นเว็บคอนเทนเนอร์:

  1. DispatcherServletจะถูกโหลดและเริ่มต้นด้วยinit()วิธีการโทร
  2. init()จากDispatcherServletจะพยายามระบุเอกสารการกำหนดค่าสปริงด้วยข้อกำหนดการตั้งชื่อเช่น "servlet_name-servlet.xml"นั้นสามารถระบุถั่วทั้งหมดได้

ตัวอย่าง:

public class DispatcherServlet extends HttpServlet {

    ApplicationContext ctx = null;

    public void init(ServletConfig cfg){
        // 1. try to get the spring configuration document with default naming conventions
        String xml = "servlet_name" + "-servlet.xml";

        //if it was found then creates the ApplicationContext object
        ctx = new XmlWebApplicationContext(xml);
    }
    ...
}

ดังนั้นในทั่วไปDispatcherServletคำขอจับ URI HandlerMappingและมือไป HandlerMappingการแม็พการค้นหา bean ด้วยเมธอดของคอนโทรลเลอร์โดยที่คอนโทรลเลอร์ส่งคืนชื่อโลจิคัล (มุมมอง) จากนั้นชื่อตรรกะนี้จะส่งให้โดยDispatcherServlet HandlerMappingจากนั้นDispatcherServletบอกViewResolverให้ให้มุมมองเต็มโดยการต่อท้ายคำนำหน้าและคำต่อท้ายจากนั้นDispatcherServletให้มุมมองให้กับลูกค้า


นี่เป็นคำอธิบายที่ดี หมายเลขจุดที่ 2 ของคุณบอกว่า DispatcherServlet จะพยายามระบุ Spring Configuration Document ด้วยแบบแผนการตั้งชื่อเช่น "servlet_name-servlet.xml" อย่างไรก็ตามฉันเคยเห็นโครงการที่ใช้ชื่อเช่น "ผู้มอบหมายงานเท่านั้น" และใช้งานได้ดี ฉันก็ลองเช่นกัน แต่ฉันไม่รู้ว่าทำไม
Subhasish Bhattacharjee

0

ดิสแพตเชอร์คอนโทรลเลอร์จะแสดงในรูปที่คำขอที่เข้ามาทั้งหมดนั้นถูกสกัดกั้นโดยเซิร์ฟเล็ตดิสแพตเชอร์ที่ทำงานเป็นตัวควบคุมด้านหน้า servlet dispatcher ได้รับรายการการแมปตัวจัดการจากไฟล์ XML และ forwords การร้องขอไปยังตัวควบคุม


-1
<?xml version='1.0' encoding='UTF-8' ?>
<!-- was: <?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:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
               http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">

    <bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping"/>
    <context:component-scan base-package="com.demo" />
    <context:annotation-config />

    <mvc:annotation-driven />


    <bean id="viewResolver"
          class="org.springframework.web.servlet.view.InternalResourceViewResolver"
          p:prefix="/WEB-INF/jsp/"
          p:suffix=".jsp" />

    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="datasource" />
    </bean> 

          <bean id="datasource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />  
        <property name="url" value="jdbc:mysql://localhost:3306/employee" />
        <property name="username" value="username" />
        <property name="password" value="password" />
    </bean> 

</beans>
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.