Що таке серветка диспетчера навесні?


195

У цьому зображенні (яке я отримав звідси ) HTTP- запит щось надсилає диспетчеру сервлету.

введіть тут опис зображення

Моє запитання - що робить диспетчер сервлет ?

Це щось на кшталт того, як викинути інформацію з веб-сторінки та передати її контролеру?

Відповіді:


202

Завдання DispatcherServlet полягає в тому, щоб взяти вхідний URI і знайти правильну комбінацію обробників (як правило, методів класів Controller ) та представлень (як правило, JSP), які поєднуються для формування сторінки або ресурсу, який повинен бути знайдений у цьому місці.

Я, можливо, мав би

  • файл /WEB-INF/jsp/pages/Home.jsp
  • і метод на уроці

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

Вантажовідправник сервлет є біт , який «знає» , щоб викликати цей метод , коли браузер запитує сторінку, і об'єднати свої результати з согласующей JSP файл , щоб зробити HTML документ.

Як це досягти, дуже залежить від конфігурації та весняної версії.

Також немає причини, щоб кінцевим результатом були веб-сторінки. Це може зробити те ж саме, щоб знайти кінцеві точки RMI , обробити запити SOAP , все, що може потрапити в сервлет.


4
Відмінно, тепер питання про те, як DispatcherServlet ідентифікує назву класу та назву методу. Чи можете ви показати мені приклад конфігурації, де у мене є два класи та два назви методу та як DispatcherServlet ловить потрібний запит.
Кевін

10
Він фактично сканує шлях класу при запуску для цієї анотації та робить відображення "/pages/Home.html" до методу Class +. Якщо у вас було два способи, в яких обидва мали "/pages/Home.html" без інших обмежень у своїй анотації, це буде помилкою, і вона кине на вас винятки. Ви також можете з'єднати його з XML, якщо ви старенькі.
Affe

2
Чи потрібен нам Dispatcher Servletфайл XML при використанні на основі анотацій @RestController?
гадюка

1
@viper в web.xml нам завжди потрібно налаштувати диспетчерський сервлет, навіть якщо ви використовуєте примітки або конфігурації xml
Mahender Reddy Yasa,

Чи є ще якийсь тип сервлетів?
Minh Nghĩa

72

У навесні MVC всі вхідні запити проходять через один сервлет. Цей сервлет -DispatcherServlet - це передній контролер. Передній контролер - типова модель дизайну в розробці веб-додатків. У цьому випадку один сервлет отримує всі запити та передає їх усім іншим компонентам програми.

Завдання DispatcherServlet - відправити запит на певний контролер Spring MVC.

Зазвичай у нас є багато контролерів і DispatcherServletдля визначення цільового контролера звертається до одного з наступних картографів:

Якщо конфігурація не виконується, DispatcherServletвикористовується BeanNameUrlHandlerMappingі DefaultAnnotationHandlerMappingза замовчуванням.

Коли ідентифікований цільовий контролер, він DispatcherServletнадсилає йому запит. Контролер виконує певну роботу відповідно до запиту (або делегує його іншим об'єктам) і повертається назад до DispatcherServlet"Модель" та назви "Вид".

Ім'я Перегляду - лише логічне ім'я. Це логічне ім'я потім використовується для пошуку фактичного представлення даних (щоб уникнути зв’язку з контролером та конкретним представленням). Потім DispatcherServletпосилається наViewResolver і відображає логічне ім'я Погляду на конкретну реалізацію Перегляду.

Деякі можливі впровадження ViewResolver:

Коли DispatcherServletвизначає представлення, яке відображатиме результати, воно буде відображатися як відповідь.

Нарешті, DispatcherServletповертає Responseоб’єкт назад клієнту.


47

DispatcherServlet- реалізація Spring MVC схеми переднього контролера .

Дивіться опис у весняних документах тут .

По суті, це сервлет, який приймає вхідний запит і делегує обробку цього запиту одному з ряду обробників, відображення яких є специфічним у DispatcherServletконфігурації.


Це щось на зразок подій у Flex, де я отримую диспетчерські події з одного MXML в інший або на сервер. Чи можу я мати в своєму додатку більше одного DispatcherServlet. У кожного файлу класу є окремий DispatcherServlet.
Кевін

Зазвичай там лише один передній контролер. Це незалежно від моделей та поглядів у вас. Він просто об'єднує конкретні моделі та погляди.
BalusC

2
@theband: Ви можете мати декілька DispatcherServlets, якщо ваша архітектура має більше сенсу, але зазвичай немає причин.
скафман

47

Я знаю, що це питання позначено як вирішене, але я хочу додати нове зображення, що детально пояснює цю модель (джерело: весна в дії 4):

введіть тут опис зображення

Пояснення

Коли запит залишає браузер (1) , він несе інформацію про те, що запитує користувач. Як мінімум, запит матиме запитувану URL-адресу. Але він також може містити додаткові дані, такі як інформація, подана користувачем у формі.

Перша зупинка в поїздці запиту - у Spring's DispatcherServlet. Як і більшість веб-рамок на базі Java, Spring MVC воронки запитує через один сервлет переднього контролера. Передній контролер - це загальна схема веб-додатків, де один сервлет делегує відповідальність за запит перед іншими компонентами програми для здійснення фактичної обробки. У випадку весняного MVC, DispatcherServlet є переднім контролером. Завдання DispatcherServlet полягає в тому, щоб надіслати запит на контролер Spring MVC. Контролер - це компонент Spring, який обробляє запит. Але типова програма може мати кілька контролерів, і DispatcherServlet потребує допомоги, щоб вирішити, до якого контролера надсилати запит. Отже, DispatcherServlet консультується з одним або декількома відображеннями обробника (2)щоб з'ясувати, де буде наступна зупинка запиту. Картограф обробника звертає особливу увагу на URL-адресу, яку має запит, приймаючи своє рішення. Після обрання відповідного контролера DispatcherServlet надсилає запит обраному контролеру (3). У контролері запит скидає свою корисну навантаження (інформацію, яку подає користувач) і терпляче чекає, поки контролер обробляє цю інформацію. (Насправді, добре розроблений контролер здійснює мало або взагалі не обробляє, а замість цього делегує відповідальність за бізнес-логіку одному або декільком об'єктам обслуговування.) Логіка, виконана контролером, часто призводить до отримання деякої інформації, яку потрібно перенести на користувача та відображається у браузері. Цю інформацію називають моделлю. Але надсилання необробленої інформації назад користувачеві недостатньо - її потрібно відформатувати у зручному для користувача форматі, як правило, у форматі HTML. Для цього інформацію потрібно надати перегляду, як правило, сторінки JavaServer (JSP). Однією з останніх речей, яку робить контролер, є упаковка даних моделі та визначення імені представлення, яке повинно надавати вихід. Потім він надсилає запит разом із моделлю та іменем перегляду назад до DispatcherServlet(4) . Так що контролер не з'єднується з певним видом, ім'я перегляду, передане назад DispatcherServlet, не визначає безпосередньо конкретний JSP. Це навіть не обов'язково говорить про те, що погляд є JSP. Натомість воно містить лише логічне ім'я, яке буде використано для пошуку фактичного виду, який дасть результат. DispatcherServlet звертається до розділювача перегляду (5) щоб відобразити ім'я логічного виду на конкретну реалізацію перегляду, яка може бути, а може і не бути JSP. Тепер, коли DispatcherServlet знає, який вид подасть результат, завдання запиту майже закінчено. Його кінцева зупинка знаходиться при здійсненні перегляду (6) , як правило, JSP, де він доставляє дані моделі. Робота запиту нарешті виконана. У поданні будуть використані дані моделі для відображення результатів, які будуть передані клієнтові об'єктом відповіді (не надто працьовитим) (7) .


У мене питання, будь ласка, як він вибирає представлення у випадку повернення об’єкта JSON, який ми бачимо у браузері, чи повертається він до того ж URI, якщо не вибрано логічний вигляд?
Nesrin

1
@Nesrin пройшло віки відтоді, коли ви запитували, але ось відповідь: ви розміщуєте спеціальну анотацію трохи вище @Controllerметоду, який називається, @ResponseBodyщо повертається відповідь має бути написаний безпосередньо в тілі відповіді HTTP, а не розміщуватися в моделі або вирішуватися як перегляд. .
інформаційна панель

6

Можна сказати, як DispatcherServletподбати про все у весняному MVC.

При запуску веб-контейнера:

  1. DispatcherServletбуде завантажений і инициализирован з допомогою виклику init()методу
  2. init()з DispatcherServletспробує ідентифікувати документ конфігурації Spring з іменування , як "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);
    }
    ...
}

Так, в загальному випадку DispatcherServletURI запиту захоплення та передачі HandlerMapping. HandlerMappingпошук на картографічному бобі методом контролера, де контролер повертає логічне ім'я (вид). Потім це логічне ім'я надсилається DispatcherServletкористувачеві HandlerMapping. Потім DispatcherServletскажіть ViewResolverнадати повне місце перегляду, додавши префікс і суфікс, а потім DispatcherServletнадайте перегляд клієнту.


Це приємне пояснення. У вашій точці №2 зазначено, що DispatcherServlet спробує ідентифікувати Весняний документ конфігурації з умовами іменування типу "servlet_name-servlet.xml". Однак я бачив проекти, які використовували лише назву "диспетчер", і це чудово працює. Я теж спробував це. Але я не знаю, чому?
Subhasish Bhattacharjee

0

Диспетчерський контролер відображається на малюнку, весь вхідний запит перехоплюється сервілетом диспетчера, який працює в якості переднього контролера. Сервлет диспетчера отримує запис для відображення обробника з XML-файлу та передає запит контролеру.


-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>
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.