Рубрики
Без рубрики

Руководство по отображению обработчиков пружин

В статье объясняется, как реализация HandlerMapping разрешает URL-адрес для конкретного обработчика.

Автор оригинала: baeldung.

1. введение

В Spring MVC DispatcherServlet действует как передний контроллер – принимает все входящие HTTP-запросы и обрабатывает их.

Проще говоря, обработка происходит путем передачи запросов соответствующему компоненту с помощью сопоставлений обработчиков .

Сопоставление обработчиков – это интерфейс, который определяет сопоставление между запросами и объектами обработчиков . В то время как Spring MVC framework предоставляет некоторые готовые реализации, интерфейс может быть реализован разработчиками для обеспечения индивидуальной стратегии отображения.

В этой статье рассматриваются некоторые реализации, предоставляемые Spring MVC, а именно BeanNameUrlHandlerMapping , SimpleUrlHandlerMapping , ControllerClassNameHandlerMapping , их конфигурация и различия между ними.

2. BeanNameUrlHandlerMapping

BeanNameUrlHandlerMapping является реализацией по умолчанию HandlerMapping . BeanNameUrlHandlerMapping сопоставляет URL-адреса запросов к бобам с тем же именем.

Это конкретное сопоставление поддерживает прямое сопоставление имен, а также сопоставление шаблонов с использованием шаблона”*”.

Например, входящий URL-адрес “/foo” сопоставляется с бобом с именем “/foo” . Примером сопоставления шаблонов является сопоставление запросов к “/foo*” бобам с именами, начинающимися с “/foo” like “/foo2/” или “/food One/” .

Давайте настроим этот пример здесь и зарегистрируем бобовый контроллер, который обрабатывает запросы к “/beannameurlha” :

@Configuration
public class BeanNameUrlHandlerMappingConfig {
    @Bean
    BeanNameUrlHandlerMapping beanNameUrlHandlerMapping() {
        return new BeanNameUrlHandlerMapping();
    }

    @Bean("/beanNameUrl")
    public WelcomeController welcome() {
        return new WelcomeController();
    }
}

Это XML-эквивалент вышеупомянутой конфигурации на основе Java:



Важно отметить, что в обеих этих конфигурациях определение компонента для BeanNameUrlHandlerMapping не требуется , как это предусмотрено Spring MVC. Удаление этого определения компонента не вызовет никаких проблем, и запросы по-прежнему будут сопоставляться с их зарегистрированными компонентами обработчика.

Теперь все запросы на “/beannameurlha” будут перенаправляться DispatcherServlet на ” WelcomeController “. WelcomeController возвращает имя представления ” welcome “.

Следующий код проверяет эту конфигурацию и гарантирует, что будет возвращено правильное имя представления:

public class BeanNameMappingConfigTest {
    // ...

    @Test
    public void whenBeanNameMapping_thenMappedOK() {
        mockMvc.perform(get("/beanNameUrl"))
          .andExpect(status().isOk())
          .andExpect(view().name("welcome"));
    }
}

3. SimpleUrlHandlerMapping

Далее, реализация SimpleUrlHandlerMapping является наиболее гибкой HandlerMapping . Он позволяет осуществлять прямое и декларативное сопоставление между экземплярами компонентов и URL-адресами или между именами компонентов и URL-адресами.

Давайте сопоставим запросы “/simple Url Welcome” и “/*/simple Url Welcome” с “welcome” bean:

@Configuration
public class SimpleUrlHandlerMappingConfig {

    @Bean
    public SimpleUrlHandlerMapping simpleUrlHandlerMapping() {
        SimpleUrlHandlerMapping simpleUrlHandlerMapping
          = new SimpleUrlHandlerMapping();
        
        Map urlMap = new HashMap<>();
        urlMap.put("/simpleUrlWelcome", welcome());
        simpleUrlHandlerMapping.setUrlMap(urlMap);
        
        return simpleUrlHandlerMapping;
    }

    @Bean
    public WelcomeController welcome() {
        return new WelcomeController();
    }
}

В качестве альтернативы, вот эквивалентная конфигурация XML:


    
        
            /simpleUrlWelcome=welcome
            /*/simpleUrlWelcome=welcome
        
    

Важно отметить, что в конфигурации XML сопоставление между тегом “” должно выполняться в форме, принятой java.util.Свойства класс и он должен следовать синтаксису: path= Handler_Bean_Name .

URL-адрес обычно должен быть с ведущей косой чертой, однако, если путь не начинается с нее, Spring MVC добавляет его автоматически.

Другой способ настроить приведенный выше пример в XML-это использовать свойство “props” вместо “value” . Props иметь список “prop” тегов, где каждый определяет сопоставление, где “ключ” ссылается на сопоставленный URL-адрес, а значение тега является именем компонента.


    
        
            welcome
            welcome
        
    

Следующий тестовый случай гарантирует, что запросы на “/ простой URL-адрес приветствия “обрабатываются” WelcomeController” , который возвращает имя представления с именем “добро пожаловать” :

public class SimpleUrlMappingConfigTest {
    // ...

    @Test
    public void whenSimpleUrlMapping_thenMappedOK() {
        mockMvc.perform(get("/simpleUrlWelcome"))
          .andExpect(status().isOk())
          .andExpect(view().name("welcome"));
    }
}

4. ControllerClassNameHandlerMapping (удалено весной 5)

ControllerClassNameHandlerMapping сопоставляет URL-адрес зарегистрированному компоненту контроллера (или контроллеру, аннотированному аннотацией @Controller ), который имеет или начинается с того же имени.

Это может быть более удобно во многих сценариях, особенно для простых реализаций контроллера, которые обрабатывают один тип запроса. Соглашение, используемое Spring MVC, состоит в том, чтобы использовать имя класса и удалить суффикс “Controller” , затем изменить имя на нижний регистр и вернуть его в качестве сопоставления с ведущим “/” .

Например, “WelcomeController” будет возвращен как сопоставление с “/welcome*” , т. Е. с любым URL-адресом, который начинается с “welcome” .

Давайте настроим ControllerClassNameHandlerMapping :

@Configuration
public class ControllerClassNameHandlerMappingConfig {

    @Bean
    public ControllerClassNameHandlerMapping controllerClassNameHandlerMapping() {
        return new ControllerClassNameHandlerMapping();
    }

    @Bean
    public WelcomeController welcome() {
        return new WelcomeController();
    }
}

Обратите внимание, что ControllerClassNameHandlerMapping устарел с Spring 4.3 в пользу методов обработчика, управляемых аннотациями.

Еще одно важное замечание заключается в том, что имена контроллеров всегда будут возвращаться в нижнем регистре (за вычетом суффикса “Контроллер”). Поэтому, если у нас есть контроллер под названием ” Welcome Baeldung Controller “, он будет обрабатывать запросы только к “/welcomebaeldung” , а не к “/welcomeBaeldung” .

Как в конфигурации Java, так и в конфигурации XML ниже мы определяем ControllerClassNameHandlerMapping bean и регистрируем бобы для контроллеров, которые мы будем использовать для обработки запросов. Мы также регистрируем компонент типа “WelcomeController” , и этот компонент будет обрабатывать все запросы, начинающиеся с “/welcome” .

Вот эквивалентная конфигурация XML:



При использовании приведенной выше конфигурации запросы на “/ welcome “будут обрабатываться” WelcomeController “.

Следующий код гарантирует, что запросы на “/ welcome *”, такие как “/ welcome test “, обрабатываются “WelcomeController”, который возвращает имя представления ” welcome “:

public class ControllerClassNameHandlerMappingTest {
    // ...

    @Test
    public void whenControllerClassNameMapping_thenMappedOK() {
        mockMvc.perform(get("/welcometest"))
          .andExpect(status().isOk())
          .andExpect(view().name("welcome"));
    }
}

5. Настройка Приоритетов

Spring MVC framework позволяет одновременно использовать несколько реализаций интерфейса HandlerMapping .

Давайте создадим конфигурацию и зарегистрируем два контроллера, оба из которых сопоставлены с URL-адресом “/welcome”, только используя разные сопоставления и возвращая разные имена представлений:

@Configuration
public class HandlerMappingDefaultConfig {

    @Bean("/welcome")
    public BeanNameHandlerMappingController beanNameHandlerMapping() {
        return new BeanNameHandlerMappingController();
    }

    @Bean
    public WelcomeController welcome() {
        return new WelcomeController();
    }
}

Если не зарегистрирован явный сопоставитель обработчиков, будет использоваться сопоставление обработчика имен Bean по умолчанию|/. Давайте подтвердим это поведение с помощью теста:

@Test
public void whenConfiguringPriorities_thenMappedOK() {
    mockMvc.perform(get("/welcome"))
      .andExpect(status().isOk())
      .andExpect(view().name("bean-name-handler-mapping"));
}

Если мы явно зарегистрируем другой сопоставитель обработчиков, сопоставитель по умолчанию будет переопределен. Однако интересно посмотреть, что происходит, когда два картографа явно зарегистрированы:

@Configuration
public class HandlerMappingPrioritiesConfig {

    @Bean
    BeanNameUrlHandlerMapping beanNameUrlHandlerMapping() {
        BeanNameUrlHandlerMapping beanNameUrlHandlerMapping 
          = new BeanNameUrlHandlerMapping();
        return beanNameUrlHandlerMapping;
    }

    @Bean
    public SimpleUrlHandlerMapping simpleUrlHandlerMapping() {
        SimpleUrlHandlerMapping simpleUrlHandlerMapping
          = new SimpleUrlHandlerMapping();
        Map urlMap = new HashMap<>();
        urlMap.put("/welcome", simpleUrlMapping());
        simpleUrlHandlerMapping.setUrlMap(urlMap);
        return simpleUrlHandlerMapping;
    }

    @Bean
    public SimpleUrlMappingController simpleUrlMapping() {
        return new SimpleUrlMappingController();
    }

    @Bean("/welcome")
    public BeanNameHandlerMappingController beanNameHandlerMapping() {
        return new BeanNameHandlerMappingController();
    }
}

Чтобы получить контроль над тем, какое отображение используется, приоритеты устанавливаются с помощью метода setOrder(int order) . Этот метод принимает один параметр int , где меньшее значение означает более высокий приоритет.

В конфигурации XML вы можете настроить приоритеты с помощью свойства “order” :


    

Давайте добавим order свойства к компонентам сопоставления обработчиков, следуя BeanNameUrlHandlerMapping.set Order(1) и simpleUrlHandlerMapping.setOrder(0). Меньшее значение свойства order отражает более высокий приоритет. Давайте утвердим новое поведение с помощью теста:

@Test
public void whenConfiguringPriorities_thenMappedOK() {
    mockMvc.perform(get("/welcome"))
      .andExpect(status().isOk())
      .andExpect(view().name("simple-url-handler-mapping"));
}

При тестировании приведенной выше конфигурации вы видите, что запросы к “/welcome” будут обрабатываться SimpleUrlHandlerMapping bean, который вызывает SimpleUrlHandlerController и возвращает simple-url-handler-mapping view. Мы можем легко настроить отображение обработчика имен Bean на приоритет, соответствующим образом настроив значения свойства order .

6. Заключение

В этой статье мы обсудили, как сопоставление URL-адресов обрабатывается в Spring MVC framework, изучив различные реализации в рамках.

Код, сопровождающий эту статью, можно найти на GitHub .