Соответствует корневому URL и показу статических ресурсов.

Моя проблема заключается в том, как настроить приложение Spring MVC для одновременного разрешения

  • приложение должно обслуживать статические ресурсы (css, js, images ...)
  • корневой URL (http://my.host.org/webb_app/) должен обслуживаться контроллером Spring

Я уже читал, как обрабатывать статический контент в Spring MVC? Использование Spring, сопоставление с root в web.xml, статические ресурсы не найдены, а Tomcat обслуживает статические ресурсы в приложении Spring MVC. Все дают рабочие решения, и до недавнего времени я использовал их в качестве рецепта приготовления, пока приложение не работает более или менее приемлемо. Все это без ссылок и четкого понимания того, почему и как это наконец сработало.

Таким образом, вопрос заключается в следующем: каковы различные способы настройки приложения Spring MVC для этого требования, каковы их недостатки и каково их обоснование.

1 ответ

Решение

Начну с предварительного замечания о том, как DefaultServlet работает. Согласно спецификациям Servlet 3.0, контейнеры обычно предоставляют сервлет по умолчанию, который имеет самый низкий приоритет и обслуживает статический контекст. Картирование / является неявным отображением для этого сервлета по умолчанию.

Теперь о решениях:

Сопоставить пружинные контроллеры с подчиненной иерархией

Это самое простое решение: вы наносите на карту Spring DispatcherServlet в /pagesили /pages а также /api например. Затем сервлет по умолчанию будет обслуживать все остальные URL-адреса (включая корневой). Чтобы обслуживать корневой контроллер, вы можете сопоставить контроллер с /home (например) и иметь /index.jsp содержащий <jsp:forward page="/home"/> - это метод текущего использования в других средах, использующих сопоставление расширений, например Struts (*.do для старых Struts1).

Недостатки: наличие URL с указанием /pages не очень приятно

Сопоставить ресурсы с подчиненной иерархией

Это решение широко используется на ссылочных страницах. весна DispatcherServlet сопоставлен с /* и таким образом получает все запросы (если не существует более конкретного отображения). Чтобы обслуживать статические ресурсы, вы просто объявляете ResourceHttpRequestHandler, используя в XML:

<mvc:resources mapping="/resources/**" location="/public-resources/"/>

или в конфигурации Java:

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/resources/**").addResourceLocations("/public-resources/");
    }
}

Это работает очень хорошо, и вы можете сопоставить контроллер Spring с / непосредственно.

Недостатки: вы не можете обслуживать статические ресурсы, которые были бы непосредственно в корневом контексте.

карта DispatcherServlet в качестве сервлета по умолчанию

Картографическая весна DispatcherServlet в / фактически заменяет сервлет по умолчанию из контейнера для обработки всех еще не обработанных URL-адресов. С помощью этого сопоставления Spring может использовать исходный сервлет по умолчанию для URL-адресов, не сопоставленных с контроллерами. Чтобы это работало, вы должны настроить DefaultServletHttpRequestHandler с отображением URL "/**" и самый низкий приоритет. Вы делаете это с помощью XML:

<mvc:default-servlet-handler/>

или в конфигурации Java:

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }

}

Сюда, DispatcherServlet обычно вызывает все контроллеры и имеет оригинальный сервлет по умолчанию для обслуживания статических (не отображаемых) ресурсов. К сожалению, это не работает для корневого URL, и вы должны использовать <jsp:forward page="..."/> трюк, как для первого решения.

Недостатки:

  • не может напрямую сопоставить корневой URL и нужен index.jsp<jsp:forward page="..."/> трюк
  • Поскольку Spring заменил оригинальный контейнерный сервлет по умолчанию, он должен вызывать его по имени. Он работает для обычных контейнеров (включая Tomcat, Jetty, GlassFish, JBoss, Resin, WebLogic и WebSphere), или вы также можете указать имя сервлета по умолчанию в качестве атрибута в конфигурации XML (<mvc:default-servlet-handler default-servlet-name="customDefaultServlet"/>) или в качестве параметра, если конфигурация Java: configurer.enable("customDefaultServlet");

Ссылки: Spring Reference Manual / Web MVC framework / Обслуживание ресурсов

Другие вопросы по тегам