Apa itu Dispatcher Servlet di Musim Semi?


195

Pada gambar ini (yang saya dapatkan dari sini ), permintaan HTTP mengirim sesuatu ke Dispatcher Servlet.

masukkan deskripsi gambar di sini

Pertanyaan saya adalah apa yang dilakukan Dispatcher Servlet ?

Apakah ini seperti mendapatkan informasi yang dilemparkan dari halaman web dan melemparkannya ke controller?

Jawaban:


202

Tugas DispatcherServlet adalah mengambil URI yang masuk dan menemukan kombinasi penangan yang tepat (umumnya metode pada kelas Kontroler ) dan tampilan (umumnya JSP) yang bergabung untuk membentuk halaman atau sumber daya yang seharusnya ditemukan di lokasi itu.

Saya mungkin punya

  • file /WEB-INF/jsp/pages/Home.jsp
  • dan metode di kelas

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

The servlet Dispatcher adalah bit yang "tahu" untuk memanggil metode yang saat browser meminta halaman, dan untuk menggabungkan hasilnya dengan pencocokan berkas JSP untuk membuat dokumen html.

Cara melakukannya bervariasi dengan konfigurasi dan versi Spring.

Tidak ada alasan mengapa hasil akhirnya adalah halaman web. Itu dapat melakukan hal yang sama untuk menemukan titik akhir RMI , menangani permintaan SOAP , apa pun yang dapat masuk ke servlet.


4
Riposte yang hebat, sekarang pertanyaan mengapa DispatcherServlet mengidentifikasi nama kelas dan nama metode juga. Bisakah Anda menunjukkan kepada saya contoh konfigurasi di mana saya memiliki dua kelas dan dua nama metode dan bagaimana DispatcherServlet menangkap permintaan yang tepat.
Kevin

10
Ini benar-benar memindai jalur kelas saat memulai untuk anotasi itu dan membuat pemetaan "/ halaman / Rumah.html" ke Metode Kelas +. Jika Anda memiliki dua metode yang keduanya memiliki "/ halaman / Rumah.html" tanpa batasan lain dalam anotasi mereka, itu akan menjadi kesalahan dan itu akan melemparkan pengecualian pada Anda. Anda juga dapat menghubungkannya dengan XML jika Anda sudah sekolah.
Terjadi

2
Apakah kita memerlukan Dispatcher Servletfile xml saat menggunakan Berbasis Anotasi @RestController?
viper

1
@ viper di web.xml kita selalu perlu mengkonfigurasi servlet dispatcher walaupun Anda menggunakan anotasi atau konfigurasi xml
Mahender Reddy Yasa

Apakah ada jenis servlet lain?
Minh Nghĩa

72

Di Spring MVC, semua permintaan masuk melewati satu servlet. Servlet ini - DispatcherServlet- adalah pengontrol depan. Pengontrol depan adalah pola desain khas dalam pengembangan aplikasi web. Dalam hal ini, satu servlet menerima semua permintaan dan mentransfernya ke semua komponen lain dari aplikasi.

Tugasnya DispatcherServletadalah mengirim permintaan ke kontroler Spring MVC tertentu.

Biasanya kami memiliki banyak pengontrol dan DispatcherServletmerujuk ke salah satu pemetaan berikut untuk menentukan pengontrol target:

Jika tidak ada konfigurasi yang dilakukan, DispatcherServletpenggunaan BeanNameUrlHandlerMappingdan DefaultAnnotationHandlerMappingsecara default.

Ketika pengontrol target diidentifikasi, DispatcherServletmengirimkan permintaan untuk itu. Pengontrol melakukan beberapa pekerjaan sesuai dengan permintaan (atau mendelegasikannya ke objek lain), dan kembali ke DispatcherServletdengan Model dan nama Tampilan.

Nama Tampilan hanya nama logis. Nama logis ini kemudian digunakan untuk mencari Tampilan aktual (untuk menghindari penggandaan dengan controller dan Tampilan spesifik). Kemudian DispatcherServletmerujuk ke ViewResolverdan memetakan nama logis Tampilan ke implementasi spesifik Tampilan.

Beberapa kemungkinan Implementasi ViewResolveradalah:

Ketika DispatcherServletmenentukan tampilan yang akan menampilkan hasil itu akan diberikan sebagai respons.

Akhirnya, DispatcherServletmengembalikan Responseobjek kembali ke klien.


47

DispatcherServletadalah implementasi Spring MVC dari pola front controller .

Lihat deskripsi di dokumen Spring di sini .

Pada dasarnya, ini adalah servlet yang mengambil permintaan masuk, dan mendelegasikan pemrosesan permintaan itu ke salah satu dari sejumlah penangan, pemetaan yang spesifik dalam DispatcherServletkonfigurasi.


Apakah itu seperti acara di Flex, di mana saya mendapatkan acara pengiriman dari satu MXML ke yang lain atau ke server. Dapatkah saya memiliki lebih dari satu DispatcherServlet di aplikasi saya. Apakah setiap file kelas memiliki DispatcherServlet yang terpisah.
Kevin

Biasanya hanya ada satu pengontrol depan. Ini terlepas dari model dan tampilan yang Anda miliki. Itu hanya menyatukan model dan tampilan tertentu.
BalusC

2
@theband: Anda dapat memiliki banyak DispatcherServlets, jika arsitektur Anda lebih masuk akal seperti itu, tetapi biasanya tidak ada alasan untuk itu.
skaffman

47

Saya tahu pertanyaan ini ditandai sudah dipecahkan tetapi saya ingin menambahkan gambar yang lebih baru yang menjelaskan pola ini secara detail (sumber: spring in action 4):

masukkan deskripsi gambar di sini

Penjelasan

Ketika permintaan meninggalkan browser (1) , ia membawa informasi tentang apa yang diminta pengguna. Paling tidak, permintaan akan membawa URL yang diminta. Tetapi itu juga dapat membawa data tambahan, seperti informasi yang dikirimkan dalam bentuk oleh pengguna.

Perhentian pertama dalam perjalanan permintaan adalah di Spring's DispatcherServlet. Seperti kebanyakan kerangka kerja web berbasis Java, Spring MVC menyalurkan permintaan melalui servlet pengontrol depan tunggal. Pengontrol depan adalah pola aplikasi web umum di mana satu servlet mendelegasikan tanggung jawab untuk permintaan ke komponen lain dari aplikasi untuk melakukan pemrosesan aktual. Dalam kasus Spring MVC, DispatcherServlet adalah pengontrol depan. Tugas DispatcherServlet adalah mengirim permintaan ke pengontrol Spring MVC. Kontroler adalah komponen pegas yang memproses permintaan. Tetapi aplikasi tipikal mungkin memiliki beberapa pengontrol, dan DispatcherServlet membutuhkan bantuan untuk memutuskan pengontrol mana yang akan dikirimi permintaan. Jadi DispatcherServlet berkonsultasi dengan satu atau lebih pemetaan pawang (2)untuk mencari tahu di mana perhentian permintaan berikutnya akan berada. Pemetaan pawang memberikan perhatian khusus pada URL yang dibawa oleh permintaan saat membuat keputusan. Setelah pengontrol yang sesuai telah dipilih, DispatcherServlet mengirimkan permintaan dengan cara yang meriah ke pengontrol yang dipilih (3). Pada controller, permintaan menurunkan muatannya (informasi yang dikirimkan oleh pengguna) dan dengan sabar menunggu sementara controller memproses informasi itu. (Sebenarnya, pengontrol yang dirancang dengan baik melakukan sedikit atau tidak sama sekali pemrosesan itu sendiri dan alih-alih mendelegasikan tanggung jawab untuk logika bisnis ke satu atau lebih objek layanan.) Logika yang dilakukan oleh pengontrol sering menghasilkan beberapa informasi yang perlu dibawa kembali ke pengguna dan ditampilkan di browser. Informasi ini disebut sebagai model. Tetapi mengirimkan informasi mentah kembali ke pengguna tidak mencukupi — itu perlu diformat dalam format yang ramah pengguna, biasanya HTML. Untuk itu, informasi perlu diberikan kepada tampilan, biasanya JavaServer Page (JSP). Salah satu hal terakhir yang dilakukan pengontrol adalah mengemas data model dan mengidentifikasi nama tampilan yang harus menampilkan output. Itu kemudian mengirimkan permintaan, bersama dengan model dan melihat nama, kembali ke DispatcherServlet(4) . Agar pengontrol tidak bisa digabungkan ke tampilan tertentu, nama tampilan yang dikembalikan ke DispatcherServlet tidak secara langsung mengidentifikasi JSP tertentu. Bahkan tidak selalu menyarankan bahwa tampilan adalah JSP. Alih-alih, itu hanya membawa nama logis yang akan digunakan untuk mencari tampilan aktual yang akan menghasilkan hasilnya. DispatcherServlet berkonsultasi dengan resolver view (5) untuk memetakan nama view logis ke implementasi tampilan spesifik, yang mungkin atau mungkin bukan JSP. Sekarang DispatcherServlet tahu tampilan mana yang akan memberikan hasilnya, pekerjaan permintaan hampir berakhir. Pemberhentian terakhir adalah pada implementasi tampilan (6), biasanya JSP, di mana ia memberikan data model. Pekerjaan permintaan itu akhirnya selesai. Pandangan akan menggunakan data model untuk membuat output yang akan dibawa kembali ke klien oleh objek respons (tidak-jadi-pekerja keras) (7) .


Saya punya pertanyaan, bagaimana ia memilih tampilan jika kembali objek JSON yang kita lihat di browser, apakah kembali ke URI yang sama jika tidak ada tampilan logis yang dipilih?
Nesrin

1
@Nesrin sudah lama sejak Anda bertanya tetapi inilah jawaban: Anda meletakkan anotasi khusus tepat di atas @Controllermetode yang disebut yang @ResponseBodymenunjukkan bahwa respons yang dikembalikan harus langsung ditulis pada badan respons HTTP, tidak untuk ditempatkan dalam Model atau diselesaikan sebagai tampilan apa pun. .
dasbor

6

Kita dapat mengatakan seperti DispatcherServletmengurus semuanya di Spring MVC.

Di wadah web mulai:

  1. DispatcherServletakan dimuat dan diinisialisasi dengan init()metode panggilan
  2. init()dari DispatcherServletakan mencoba mengidentifikasi Dokumen Konfigurasi Spring dengan konvensi penamaan seperti "servlet_name-servlet.xml"semua kacang dapat diidentifikasi.

Contoh:

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);
    }
    ...
}

Jadi, secara umum DispatcherServlettangkap permintaan URI dan serahkan ke HandlerMapping. HandlerMappingcari pemetaan kacang dengan metode pengontrol, di mana pengontrol mengembalikan nama logis (tampilan). Maka nama logis ini dikirim ke DispatcherServletoleh HandlerMapping. Kemudian DispatcherServletberi tahu ViewResolveruntuk memberikan lokasi tampilan penuh dengan menambahkan awalan dan akhiran, kemudian DispatcherServletberikan tampilan kepada klien.


Ini penjelasan yang bagus. Poin 2 Anda mengatakan bahwa DispatcherServlet akan mencoba mengidentifikasi Dokumen Konfigurasi Spring dengan konvensi penamaan seperti "servlet_name-servlet.xml". Namun, saya telah melihat proyek yang menggunakan nama seperti "operator" saja, dan itu berfungsi dengan baik. Saya juga sudah mencobanya. Tapi saya tidak tahu kenapa?
Subhasish Bhattacharjee

0

Pengendali Dispatcher ditampilkan pada gambar, semua permintaan yang masuk dicegat oleh servlet operator yang berfungsi sebagai pengontrol depan. Servlet dispatcher mendapat entri untuk pemetaan handler dari file XML dan meramalkan permintaan ke Controller.


-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>
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.