Автор оригинала: 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!
">
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!
" />
Стоит отметить, что, начиная с 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 .