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

Обслуживайте статические ресурсы с помощью Spring

Как сопоставлять и обрабатывать статические ресурсы с помощью Spring MVC – используйте простую конфигурацию, затем более гибкую конфигурацию 3.1 и, наконец, новые распознаватели ресурсов 4.1.

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

1. Обзор

В этой статье рассматривается, как обслуживать статические ресурсы с помощью Spring – с использованием конфигурации XML и Java.

Дальнейшее чтение:

Кэшируемые статические активы с помощью Spring MVC

Введение в веб-семинары

Минимизация ресурсов JS и CSS с помощью Maven

2. Использование Пружинного Ботинка

Spring Boot поставляется с предварительно настроенной реализацией ResourceHttpRequestHandler для облегчения обслуживания статических ресурсов.

По умолчанию этот обработчик обслуживает статическое содержимое из любого каталога /static,/public,/resources, и META-INF/resources , который находится в пути к классу . Поскольку src/main/resources обычно по умолчанию находится в пути к классу, мы можем разместить там любой из этих каталогов.

Например, если мы поставим about.html файл внутри каталога /static в вашем пути к классу, затем мы можем получить доступ к этому файлу через http://localhost:8080/about.html . Аналогично, мы можем достичь того же результата, добавив этот файл в другие упомянутые каталоги.

2.1. Пользовательские шаблоны Путей

По умолчанию Spring Boot обслуживает все статическое содержимое в корневой части запроса, то есть /** . Несмотря на то, что это хорошая конфигурация по умолчанию, мы можем изменить ее с помощью свойства spring.mvc.static-path-pattern | configuration.

Например, если мы хотим получить доступ к одному и тому же файлу через http://localhost:8080/content/about.html, мы можем сказать это в нашем application.properties:

spring.mvc.static-path-pattern=/content/**

В средах WebFlux мы должны использовать свойство spring.webflux.static-path-pattern .

2.2. Пользовательские каталоги

Аналогично шаблонам путей, также можно изменить расположение ресурсов по умолчанию с помощью свойства конфигурации spring.resources.static-locations |. Это свойство может принимать несколько расположений ресурсов, разделенных запятыми :

spring.resources.static-locations=classpath:/files/,classpath:/static-files

Здесь мы обслуживаем статическое содержимое из каталогов /files и /static-files внутри пути к классу. Кроме того, Spring Boot может обслуживать статические файлы из-за пределов пути к классу :

spring.resources.static-locations=file:/opt/files

Здесь мы используем сигнатуру file resource , file:/ для обслуживания файлов с нашего локального диска.

3. Конфигурация XML

Если вам нужно пойти по старому пути с конфигурацией на основе XML, вы можете хорошо использовать элемент mvc:resources , чтобы указать местоположение ресурсов с определенным общедоступным шаблоном URL.

Например, следующая строка будет обслуживать все запросы на ресурсы, поступающие с общедоступным шаблоном URL-адреса, например ” /ресурсы/** “, путем поиска в каталоге “/ ресурсы/ ” в корневой папке нашего приложения.

Теперь мы можем получить доступ к CSS-файлу, как на следующей HTML-странице:

Пример 3.1.

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>


    " rel="stylesheet">
    Home


    

Hello world!

4. ResourceHttpRequestHandler

Весна 3.1. ввела Resource Hand ler Registry для настройки ResourceHttpRequestHandler s для обслуживания статических ресурсов из пути к классам, ВОЙНЫ или файловой системы. Мы можем настроить ResourceHandlerRegistry программно в нашем классе конфигурации веб-контекста.

4.1. Обслуживание Ресурса, хранящегося в ВОЙНЕ

Чтобы проиллюстрировать это, мы будем использовать тот же URL-адрес , что и раньше, чтобы указать на myCss.css , но теперь фактический файл будет находиться в папке webapp/resources WAR, в которой должны размещаться статические ресурсы при развертывании приложений Spring 3.1+:

Пример 4.1.1.

@Configuration
@EnableWebMvc
public class MvcConfig implements WebMvcConfigurer {
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry
          .addResourceHandler("/resources/**")
          .addResourceLocations("/resources/");	
    }
}

Давайте проанализируем этот пример. Во-первых, мы настраиваем внешний путь URI, добавляя определение обработчика ресурсов. Затем мы сопоставляем этот внешний URI-путь внутренне с физическим путем, где на самом деле находятся ресурсы.

Конечно, мы можем определить несколько обработчиков ресурсов, используя этот простой, но гибкий API.

Теперь – следующая строка на странице html приведет нас к ресурсу myCss.css внутри каталога webapp/resources :

" rel="stylesheet">

4.2. Обслуживание ресурса, хранящегося в Файловой системе

Допустим, мы хотим обслуживать ресурс, хранящийся в каталоге /opt/files/ всякий раз, когда поступает запрос на общедоступный URL-адрес, соответствующий шаблону: /files/** . Мы просто настраиваем шаблон URL-адреса и сопоставляем его с этим конкретным местоположением на диске:

Пример 4.2.1.

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry
      .addResourceHandler("/files/**")
      .addResourceLocations("file:/opt/files/");
 }

*(Для пользователей Windows: аргумент, переданный в addResourceLocations для этого примера, будет ” file:///C:/opt/files/ “).

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

Пример 4.2.2.

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>


    " rel="stylesheet">
    Home


    

Hello world!

image">

4.3. Настройка нескольких местоположений для ресурса

Что делать, если мы хотим искать ресурс в нескольких местах?

Мы можем включить несколько местоположений с помощью метода addResourceLocations . Список местоположений будет искать по порядку, пока ресурс не будет найден. Давайте рассмотрим пример 3.3.1.

Пример 4.3.1

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

Следующий запрос curl отобразит Hello.html страница, хранящаяся либо в папке webapp/resources приложения, либо в папке other-resources в пути к классу.

curl -i http://localhost:8080/handling-spring-static-resources/resources/Hello.html

5. Новый Решатель ресурсов

Spring 4.1. предоставляет – с новыми ResourcesResolvers – различные типы распознавателей ресурсов, которые можно использовать для оптимизации производительности браузера при загрузке статических ресурсов. Эти распознаватели могут быть объединены в цепочку и кэшированы в браузере для оптимизации обработки запросов.

5.1. Решатель PathResourceResolver

Это самый простой распознаватель, и его цель состоит в том, чтобы найти ресурс, заданный общедоступным шаблоном URL. На самом деле, если ResourceResolver не добавлен в Регистрацию цепочки ресурсов , это распознаватель по умолчанию.

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

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry
      .addResourceHandler("/resources/**")
      .addResourceLocations("/resources/","/other-resources/")
      .setCachePeriod(3600)
      .resourceChain(true)
      .addResolver(new PathResourceResolver());
}

Вещи, которые нужно заметить:

  • Мы регистрируем PathResourceResolver в цепочке ресурсов в качестве единственного ResourceResolver в ней. См. раздел 4.3. чтобы проверить, как связать более одного ResourceResolver .
  • Обслуживаемые ресурсы будут кэшироваться в браузере в течение 3600 секунд.
  • Цепочка окончательно настраивается с помощью метода resource Chain(true) .

Теперь – HTML-код, который в сочетании с PathResourceResolver находит foo.js скрипт в папке webapp/resources папки webapp/other-resources :

">

5.2. Кодированный решатель ресурсов

Этот распознаватель пытается найти закодированный ресурс на основе значения заголовка Accept-Encoding request.

Например, нам может потребоваться оптимизировать пропускную способность, обслуживая сжатую версию статического ресурса с использованием gzip кодирования содержимого.

Чтобы настроить Кодированный ResourceResolver, нам просто нужно настроить его в цепочке Ресурсов так же , как мы настроили PathResourceResolver , как в следующей строке кода:

registry
  .addResourceHandler("/other-files/**")
  .addResourceLocations("file:/Users/Me/")
  .setCachePeriod(3600)
  .resourceChain(true)
  .addResolver(new EncodedResourceResolver());

По умолчанию Encoded ResourceResolver настроен на поддержку br и gzip кодирования.

Таким образом, следующий запрос curl получит заархивированную версию Home.html файл, расположенный в файловой системе в каталоге Users/Me/ :

curl -H  "Accept-Encoding:gzip" 
  http://localhost:8080/handling-spring-static-resources/other-files/Hello.html

Обратите внимание, как мы устанавливаем значение заголовка “ Accept-Encoding ” в gzip – это важно, потому что этот конкретный распознаватель будет работать только в том случае, если содержимое gzip допустимо для ответа.

Наконец, обратите внимание, что, как и раньше, сжатая версия будет оставаться доступной в течение периода времени, в течение которого она кэшируется в браузере, что в данном случае составляет 3600 секунд.

5.3. Цепные решатели ресурсов

Чтобы оптимизировать поиск ресурсов, Распознаватели ресурсов могут делегировать обработку ресурсов другим распознавателям. Единственный распознаватель, который не может делегировать цепочку, – это PathResourceResolver , который должен быть добавлен в конце цепочки.

На самом деле, если цепочка ресурсов не имеет значения true , то по умолчанию для обслуживания ресурсов будет использоваться только PathResourceResolver . В примере 4.3.1. мы связываем PathResourceResolver для разрешения ресурса, если Gzip ResourceResolver не удается.

Пример 5.3.1.

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry
      .addResourceHandler("/js/**")
      .addResourceLocations("/js/")
      .setCachePeriod(3600)
      .resourceChain(true)
      .addResolver(new GzipResourceResolver())
      .addResolver(new PathResourceResolver());
}

Теперь , когда мы добавили шаблон /js/** в ResourceHandler , давайте включим foo.js ресурс, расположенный в каталоге webapp/js/ в нашем home.html страница, как в примере 4.3.2.

Пример 5.3.2.

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>


    " rel="stylesheet" />
    ">
    Home


    

This is Home!

bunny hop image" />

Стоит отметить, что, начиная с Spring Framework 5.1, GzipResourceResolver устарел в пользу EncodedResourceResolver . Поэтому мы должны избегать его использования в будущем.

6. Дополнительная конфигурация Безопасности

При использовании Spring Security – важно разрешить доступ к статическим ресурсам. Нам нужно будет добавить соответствующие разрешения для доступа к URL-адресу ресурса:




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

В этой статье мы проиллюстрировали различные способы, с помощью которых приложение Spring может обслуживать статические ресурсы.

Конфигурация ресурсов на основе XML-это “устаревший” вариант , который мы можем использовать, если мы еще не можем пройти по маршруту конфигурации Java.

Весна 3.1. вышла с базовой программной альтернативой через свой ResourceHandlerRegistry объект.

И, наконец, – новые готовые ResourceResolvers и ResourceChainRegistration object , поставляемые с Spring 4.1 . предлагают функции оптимизации загрузки ресурсов, такие как кэширование и цепочка обработчиков ресурсов, для повышения эффективности обслуживания статических ресурсов.

Как всегда, полный пример доступен на Github . Кроме того, в этом проекте также доступны исходные коды, связанные с Spring Boot .