Статическое содержимое

По умолчанию Spring Boot обрабатывает статическое содержимое из каталога /static (или /public или /resources, или /META-INF/resources) в classpath или из корня ServletContext. Фреймворк использует ResourceHttpRequestHandler из Spring MVC, поэтому вы можете изменить эту логику работы, добавив свой собственный WebMvcConfigurer и переопределив метод addResourceHandlers.

В автономном веб-приложении стандартный сервлет из контейнера не активирован. Его можно активировать с помощью свойства server.servlet.register-default-servlet.

Стандартный сервлет выступает в роли запасного варианта, обрабатывая содержимое из корня ServletContext, если Spring не будет обрабатывать его. В большинстве случаев такого не происходит (если не изменить стандартную конфигурацию MVC), потому что Spring всегда способен обрабатывать запросы через DispatcherServlet.

По умолчанию ресурсы отображаются на /**, но можно тонко настроить это отображение через свойство spring.mvc.static-path-pattern. Например, перемещение всех ресурсов в /resources/** можно выполнить следующим образом:

Properties
spring.mvc.static-path-pattern=/resources/**
Yaml
spring:
  mvc:
    static-path-pattern: "/resources/**"

Вы также можете настраивать расположение статических ресурсов с помощью свойства spring.web.resources.static-locations (заменив значения по умолчанию на список местоположений каталогов). Корневой путь контекста сервлета, "/", автоматически добавляется в качестве местоположения.

В дополнение к "стандартным" статическим местоположениям ресурсов, упомянутым ранее, особое место отводится содержимому Webjars. Любые ресурсы с путем в /webjars/** обрабатываются из jar-файлов, если они упакованы в формат Webjars.

Не используйте каталог src/main/webapp, если приложение упаковано в виде jar-файла. Хотя данный каталог является общепринятым стандартом, он работает исключительно с упаковкой в war, и он молча игнорируется большинством инструментальных средств сборки, если генерируется jar-файл.

Spring Boot также поддерживает расширенный функционал работы с ресурсами, предоставляемыми Spring MVC, что позволяет использовать такие сценарии, как отключение кэширования статических ресурсов или использование URL-адресов для Webjars, не зависящие от версии.

Чтобы использовать URL-адреса Webjars, не зависящие от версии, добавьте зависимость webjars-locator-core. Затем объявите свой Webjar. На примере jQuery добавление "/webjars/jquery/jquery.min.js" приводит к "/webjars/jquery/x.y.z/jquery.min.js", где x.y.z – версия Webjar.

Если вы используете JBoss, то нужно объявить зависимость webjars-locator-jboss-vfs вместо webjars-locator-core. В противном случае все Webjars разрешаются как 404.

Для использования функции отключения кэширования в следующей конфигурации сконфигурировано решение для отключения кэширования всех статических ресурсов путем добавления хэша содержимого, например <link href="/css/spring-2a2d595e6ed9a0b24f027f2b63b134d6.css"/>, в URL-адрес:

Properties
spring.web.resources.chain.strategy.content.enabled=true
spring.web.resources.chain.strategy.content.paths=/**
Yaml
spring:
  web:
    resources:
      chain:
        strategy:
          content:
            enabled: true
            paths: "/**"
Ссылки на ресурсы переписываются в шаблонах во время выполнения благодаря ResourceUrlEncodingFilter, который автоматически конфигурируется для Thymeleaf и FreeMarker. Следует вручную объявить этот фильтр при использовании JSP. Другие шаблонизаторы в настоящее время не поддерживаются в автоматическом порядке, но их поддержку можно обеспечить с помощью кастомных шаблонных макросов/вспомогательных классов и использования ResourceUrlProvider.

При динамической загрузке ресурсов, например, с помощью загрузчика модулей JavaScript, переименование файлов невозможно. Поэтому поддерживаются и другие стратегии, которые можно комбинировать. Стратегия с использованием "фиксации (fixed)" добавляет статическую строку версии в URL-адрес без изменения имени файла, как показано в следующем примере:

Properties
spring.web.resources.chain.strategy.content.enabled=true
spring.web.resources.chain.strategy.content.paths=/**
spring.web.resources.chain.strategy.fixed.enabled=true
spring.web.resources.chain.strategy.fixed.paths=/js/lib/
spring.web.resources.chain.strategy.fixed.version=v12
Yaml
spring:
  web:
    resources:
      chain:
        strategy:
          content:
            enabled: true
            paths: "/**"
          fixed:
            enabled: true
            paths: "/js/lib/"
            version: "v12"

При такой конфигурации модули JavaScript, расположенные в каталоге "/js/lib/", используют стратегию фиксированного версионирования ("/v12/js/lib/mymodule.js"), в то время как другие ресурсы по-прежнему используют стратегию на основе содержимого (<link href="/css/spring-2a2d595e6ed9a0b24f027f2b63b134d6.css"/>).

Дополнительные поддерживаемые опции см. в WebProperties.Resources.

Данная функция была подробно описана в специальном посте в блоге и в справочной документации Spring Framework.

Начальная страница

Spring Boot поддерживает как статические, так и шаблонные начальные страницы. Сначала фреймворк ищет файл index.html в сконфигурированных местоположениях статического содержимого. Если такой шаблон не найден, он ищет шаблон index. Если один из них будет найден, то он будет автоматически использован в качестве начальной страницы приложения.

Кастомный Favicon

Как и в случае с другими статическими ресурсами, Spring Boot проверяет наличие favicon.ico в сконфигурированных местоположениях статического контента. Если такой файл присутствует, он автоматически используется в качестве значка веб-страницы (favicon) для приложения.

Сопоставление путей и согласование содержимого

Spring MVC может сопоставлять входящие HTTP-запросы с обработчиками, просматривая путь запроса и сопоставляя его с отображениями, определенными в приложении (например, аннотациями @GetMapping для методов контроллера).

Spring Boot по умолчанию отключает сопоставление суффиксальных шаблонов, что означает, что запросы типа "GET /projects/spring-boot.json" не будут сопоставлены с отображениями @GetMapping("/projects/spring-boot"). Это считается наиболее оптимальным методом для приложений Spring MVC. В прошлом данная функция была полезна в основном для HTTP-клиентов, которые не отправляли надлежащие заголовки запроса "Accept"; необходимо было убедиться, что клиенту отправлен корректный тип содержимого. В настоящее время согласование содержимого стало намного надежнее.

Существуют и другие способы разобраться с HTTP-клиентами, которые не всегда отправляют правильные заголовки запроса "Accept". Вместо использования суффиксального соответствия можно использовать параметр запроса, чтобы запросы типа "GET /projects/spring-boot?format=json" были гарантированно сопоставлены с @GetMapping("/projects/spring-boot"):

Properties
spring.mvc.contentnegotiation.favor-parameter=true
Yaml
spring:
  mvc:
    contentnegotiation:
      favor-parameter: true

Или если вы предпочитаете использовать другое имя параметра:

Properties
spring.mvc.contentnegotiation.favor-parameter=true
spring.mvc.contentnegotiation.parameter-name=myparam
Yaml
spring:
  mvc:
    contentnegotiation:
      favor-parameter: true
      parameter-name: "myparam"

Большинство стандартных типов среды передачи данных поддерживаются "из коробки", но вы также можете определять новые:

Properties
spring.mvc.contentnegotiation.media-types.markdown=text/markdown
Yaml
spring:
  mvc:
    contentnegotiation:
      media-types:
        markdown: "text/markdown"

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

Properties
spring.mvc.contentnegotiation.favor-path-extension=true
spring.mvc.pathmatch.use-suffix-pattern=true
Yaml
spring:
  mvc:
    contentnegotiation:
      favor-path-extension: true
    pathmatch:
      use-suffix-pattern: true

Кроме того, вместо открытия всех суффиксальных шаблонов более надежным методом будет обеспечение поддержки исключительно зарегистрированных суффиксальных шаблонов:

Properties
spring.mvc.contentnegotiation.favor-path-extension=true
spring.mvc.pathmatch.use-registered-suffix-pattern=true
Yaml
spring:
  mvc:
    contentnegotiation:
      favor-path-extension: true
    pathmatch:
      use-registered-suffix-pattern: true

Начиная с версии Spring Framework 5.3, Spring MVC поддерживает несколько стратегий реализации для сопоставления путей запроса с обработчиками контроллера. Ранее она поддерживала только стратегию AntPathMatcher, но теперь также предлагает и PathPatternParser. Spring Boot теперь предусматривает конфигурационное свойство, обеспечивающее выбор и подключение новой стратегии:

Properties
spring.mvc.pathmatch.matching-strategy=path-pattern-parser
Yaml
spring:
  mvc:
    pathmatch:
      matching-strategy: "path-pattern-parser"

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

PathPatternParser является оптимизированной реализацией, но ограничивает использование некоторых вариантов шаблонов путей и несовместима с сопоставлением суффиксальных шаблонов (spring.mvc.pathmatch.use-suffix-pattern, spring.mvc.pathmatch.use-registered-suffix-pattern) или отображением DispatcherServlet с префиксом сервлета (spring.mvc.servlet.path).

ConfigurableWebBindingInitializer

Spring MVC использует WebBindingInitializer для инициализации WebDataBinder для конкретного запроса. Если вы создадите свой собственный ConfigurableWebBindingInitializer, помеченный аннотацией @Bean, Spring Boot автоматически сконфигурирует Spring MVC на его использование.