Как я могу переопределить значок Spring Boot?
ПРИМЕЧАНИЕ . Вот еще один мой вопрос, который предлагает другое решение, не связанное с кодированием: Spring Boot: можно ли использовать внешние файлы application.properties в произвольных каталогах с толстой банкой? Это для application.properties, но его также можно применить к значку. Фактически, я сейчас использую этот метод для переопределения значков.
Если я реализую класс с @EnableWebMvc, класс WebMvcAutoConfiguration Spring Boot не загружается, и я могу обслуживать свой собственный значок, помещая его в корневой каталог статического содержимого.
В противном случае WebMvcAutoConfiguration регистрирует bean-компонент faviconRequestHandler (см. Источник https://github.com/spring-projects/spring-boot/blob/master/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconframework/boot/autoconfigure/ web / WebMvcAutoConfiguration.java ), и он обслуживает значок «зеленый лист», который помещается в основной каталог ресурсов Spring Boot.
Как я могу переопределить его, не реализуя класс, который сам имеет @EnableWebMvc, тем самым отключив всю функциональность конфигурации по умолчанию для класса WebMvcAutoConfiguration класса Spring Boot?
Кроме того, поскольку я хочу, чтобы файл значка был обновлен как можно скорее на стороне клиента (веб-браузера), я хочу установить период кеширования файла значка на 0. (например, следующий код, который я использую для своего «статический» контент веб-приложения и файлы сценариев, которые должны быть обновлены на стороне клиента как можно скорее после того, как я изменю файл.)
public void addResourceHandlers(ResourceHandlerRegistry registry)
{
registry.addResourceHandler("/**")
.addResourceLocations("/")
.setCachePeriod(0);
}
Итак, просто найти место для сохранения файла favicon.ico, который уважает Spring Boot faviconRequestHandler, может быть недостаточно.
ОБНОВИТЬ
Теперь я знаю, что могу изменить значение по умолчанию, поместив файл значка в каталог src / main / resources. Но проблема периода кеширования все еще остается.
Кроме того, предпочтительно помещать файл значка в каталог, в который помещаются статические веб-файлы, а не в каталог ресурсов.
ОБНОВИТЬ
Хорошо, мне удалось изменить значение по умолчанию. Я сделал следующее:
@Configuration
public class WebMvcConfiguration
{
@Bean
public WebMvcConfigurerAdapter faviconWebMvcConfiguration()
{
return new FaviconWebMvcConfiguration();
}
public class FaviconWebMvcConfiguration extends WebMvcConfigurerAdapter
{
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry)
{
registry.setOrder(Integer.MIN_VALUE);
registry.addResourceHandler("/favicon.ico")
.addResourceLocations("/")
.setCachePeriod(0);
}
}
}
По сути, я отменял стандартное, добавляя обработчик ресурсов с наивысшим порядком, вызывая registry.setOrder (Integer.MIN_VALUE).
Поскольку значение по умолчанию в Spring Boot имеет значение порядка (Integer.MIN_VALUE + 1) (см. Класс FaviconConfiguration в https://github.com/spring-projects/spring-boot/blob/master/spring-boot-autoconfigure/ src / main / java / org / springframework / boot / autoconfigure / web / WebMvcAutoConfiguration.java ) мой обработчик побеждает.
Это нормально? Есть ли другой способ (что-то более мягкое, чем то, что я сделал)?
ОБНОВИТЬ
Это не хорошо. Когда я звоню registry.setOrder(Integer.MIN_VALUE)
, я фактически повышаю приоритет всех обработчиков ресурсов. Итак, когда я добавляю следующий код к другому WebMvcConfigurerAdapter
, фактически весь HTTP-запрос направляется этому обработчику ресурсов, предотвращая любую динамическую обработку кодом Java.
public void addResourceHandlers(ResourceHandlerRegistry registry)
{
registry.addResourceHandler("/**")
.addResourceLocations("/")
.setCachePeriod(0);
}
Требуется другое решение.
ОБНОВИТЬ
На данный момент я не смог найти способ переопределить функциональность значка, предоставляемую Spring Boot.
Может есть способ добавить свойHandlerMapping
bean-компонент, но я не знаю, как это сделать.
Теперь я могу выбрать один из следующих вариантов:
- Имейте класс, который
@EnableWebMvc
отключилWebMvcAutoConfiguration
класс Spring Boot . (Я могу скопировать кодWebMvcAutoConfiguration
класса и удалить функцию фавикона) - Откажитесь от свободы размещения файла значка в произвольном месте и поместите его в каталог ресурсов, как того требует функциональность значков Spring Boot. И игнорируйте проблему кеширования.
Но ни один из вариантов не является удовлетворительным.
Я просто хочу разместить файл значка со своими статическими веб-файлами (это может быть любой каталог, поскольку я могу изменить корень документа) и решить проблему кеширования.
Я что-то упускаю?
Любое предложение будет принято с благодарностью.
ОБНОВИТЬ
Кстати, причина, по которой я хочу изменить расположение значка и других статических файлов, заключается в следующем. Пока это в основном проблема среды разработки.
Я создаю одностраничное веб-приложение (SPA).
Библиотеки / Фреймворки:
- На стороне сервера я использую Spring. (конечно)
- На стороне клиента (веб-браузера) я использую AngularJS.
Инструменты:
- На стороне сервера я использую Spring Tool Suite.
- На стороне клиента я использую WebStorm.
Структура основного каталога:
ProjectRoot\
src\
bin\
build\
webapp\
build.gradle
- src: Где находятся мои исходные файлы Java Spring.
- bin: Где Spring Tool Suite размещает свои выходные данные сборки.
- build: где gradle build размещает вывод сборки.
- webapp: Где находятся мои исходные файлы клиента (.js, .css, .htm и favicon). Таким образом, это каталог проекта WebStorm. (При необходимости я могу изменить имя каталога)
Я хочу:
- Чтобы иметь возможность изменять и тестировать мой клиентский код без перестройки / перезапуска моего серверного приложения Spring. Таким образом, код клиента нельзя помещать в файл jar. В любом случае Spring Tool Suite вообще не создает файл jar (по крайней мере, для текущей конфигурации)
- Чтобы иметь возможность тестировать мое серверное приложение Spring с клиентским кодом, легко переключаясь между выходом Spring Tool Suite и выходом gradle. Таким образом, клиентский код должен быть доступен как из серверного приложения в
build
подкаталоге (фактическиbuild\libs
), так и из серверного приложения вbin
каталоге. - Когда я изменяю код клиента, он должен быть немедленно доступен для веб-браузера. Таким образом, браузер не должен кэшировать его на неопределенный срок и всегда должен запрашивать обновление у сервера.
- При развертывании клиентский код должен быть изменяемым без перекомпоновки / перезапуска серверного приложения. Поэтому код клиента нельзя помещать в файл jar.
Что касается проблемы с кешем:
Без setCachePeriod (0) в addResourceHandlers () Google Chrome кэширует файл на неопределенный срок, не запрашивая обновления у сервера. Он даже не подключается к серверу. (Инженеры Google говорят, что поведение правильное.) Итак, все, что я могу сделать, это вручную очистить кеш браузера. Это расстраивает среду разработки и неприемлемо для производственной среды.
Кстати, модуль express.js на Node.js предоставляет разумный HTTP-заголовок по умолчанию, чтобы Google Chrome запрашивал у сервера обновления. Когда я просмотрел заголовки HTTP, которые Spring и express.js создают с помощью Fiddler, они были разными.
Любые предложения по улучшению моей среды будут оценены.
Поскольку я новичок в Spring, возможно, мне что-то не хватает.
ОБНОВИТЬ
Наконец-то у меня есть рабочий код. Это выглядит следующим образом:
@Configuration
public static class FaviconConfiguration
{
@Bean
public SimpleUrlHandlerMapping myFaviconHandlerMapping()
{
SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping();
mapping.setOrder(Integer.MIN_VALUE);
mapping.setUrlMap(Collections.singletonMap("/favicon.ico",
myFaviconRequestHandler()));
return mapping;
}
@Autowired
ApplicationContext applicationContext;
@Bean
protected ResourceHttpRequestHandler myFaviconRequestHandler()
{
ResourceHttpRequestHandler requestHandler =
new ResourceHttpRequestHandler();
requestHandler.setLocations(Arrays
.<Resource> asList(applicationContext.getResource("/")));
requestHandler.setCacheSeconds(0);
return requestHandler;
}
}
Обратите внимание на имена бобов. Я добавил «мой», чтобы избежать конфликта имен.
Сам по себе контекст приложения Autowiring кажется неудобным, но он был необходим для имитации кода org.springframework.web.servlet.config.annotation.ResourceHandlerRegistration.addResourceLocations()
.
Теперь у меня есть обработчик значков без проблем с кешированием, и я могу разместить файл значков в любом месте.
Благодарю.
classpath:/static
). (Вот почему поддержка значков в Boot, я думаю, находится в собственном HandlerMapping.)