Как я могу переопределить значок Spring Boot?
ПРИМЕЧАНИЕ. Вот мой еще один вопрос, который предлагает другое решение, которое не требует какого-либо кодирования: Spring Загрузка: возможно ли использовать внешнее приложение .properties в произвольных каталогах с толстым банком? Это для application.properties, но оно также может быть применено к значку. На самом деле, я использую этот метод для переопределения favicon.
Если я реализую класс с @EnableWebMvc, класс WebMvcAutoConfiguration Spring Boot не загружается, и я могу обслуживать свой собственный значок, поместив его в корневую директорию статического содержимого.
В противном случае WebMvcAutoConfiguration регистрирует faviconRequestHandler bean (см. источник https://github.com/spring-projects/spring-boot/blob/master/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration.java), и он служит значку "зеленый лист", который помещен в каталоге ресурсов Spring Boot main.
Как я могу переопределить его, не внедряя сам класс, который имеет @EnableWebMvc, тем самым отключив все функции настройки по умолчанию для класса WebMvcAutoConfiguration Spring Boot?
Кроме того, поскольку я хочу, чтобы файл значка был обновлен как можно скорее на стороне клиента (веб-браузера), я хочу установить период кэширования файла favicon равным 0. (например, следующий код, который я используя мой "статический" контент webapp и script файлы, которые должны быть обновлены на стороне клиента как можно скорее после изменения файла.)
public void addResourceHandlers(ResourceHandlerRegistry registry)
{
registry.addResourceHandler("/**")
.addResourceLocations("/")
.setCachePeriod(0);
}
Итак, просто чтобы найти место для сохранения файла favicon.ico, что Spring Похвала faviconRequestHandler загрузки может быть недостаточной.
UPDATE
Теперь я знаю, что могу переопределить значение по умолчанию, поместив файл favicon в каталог src/main/resources. Но проблема с периодом кеша все еще сохраняется.
Кроме того, предпочтительно размещать файл favicon в каталоге, где размещены статические веб файлы, а не каталог ресурсов.
UPDATE
Хорошо, мне удалось переопределить значение по умолчанию. Я сделал следующее:
@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) побеждает мой обработчик.
Это хорошо? Есть ли другой способ (что-то более мягкое, чем то, что я сделал)?
UPDATE
Это не так.
Когда я вызываю registry.setOrder(Integer.MIN_VALUE)
, на самом деле я поднимаю приоритет всех обработчиков ресурсов. Поэтому, когда я добавляю следующий код в другой WebMvcConfigurerAdapter
, фактически весь HTTP-запрос направляется на этот обработчик ресурсов, предотвращая любую динамическую обработку кодом Java.
public void addResourceHandlers(ResourceHandlerRegistry registry)
{
registry.addResourceHandler("/**")
.addResourceLocations("/")
.setCachePeriod(0);
}
Требуется другое решение.
UPDATE
В настоящее время я не могу найти способ переопределить функциональность favicon Spring Boot.
Возможно, есть способ добавить добавить свой собственный HandlerMapping
bean, но я не знаю, как это сделать.
Теперь я могу выбрать один из следующих вариантов:
- У класса с
@EnableWebMvc
таким образом отключается класс Spring BootWebMvcAutoConfiguration
. (Я могу скопировать код классаWebMvcAutoConfiguration
и удалить функциональность favicon) - Откажитесь от свободы размещения файла favicon в суровом местоположении и поместите его в каталог ресурсов в качестве Spring для функции загрузки favicon. И игнорируйте проблему кэширования.
Но ни один из вариантов не является удовлетворительным.
Я просто хочу разместить файл favicon с моими статическими веб файлами (которые могут быть любой директорией, так как я могу изменить корень документа) и решить проблему кеширования.
Я что-то не хватает?
Любое предложение было бы с благодарностью.
UPDATE
Кстати, причина, по которой я хочу изменить местоположение favicon и других статических файлов, выглядит следующим образом. На данный момент это в основном проблема среды разработки.
Я создаю одностраничное веб-приложение (SPA).
Библиотеки/Каркасы:
- Для серверной части я использую Spring. (конечно)
- Для стороннего клиента (веб-браузера) я использую AngularJS.
Инструменты:
- Для серверной части я использую Spring Tool Suite.
- Для клиентской стороны я использую WebStorm.
Основная структура каталогов:
ProjectRoot\
src\
bin\
build\
webapp\
build.gradle
- src: Где находятся мои исходные файлы java Spring.
- bin: Где Spring Инструмент Suite помещает свой вывод сборки.
- build: Where 'gradle build' помещает свой вывод сборки.
- webapp: Где находятся мои исходные файлы клиента (.js,.css,.htm и favicon). Таким образом, это каталог проектов WebStorm. (При необходимости я могу изменить имя каталога)
Я хочу:
- Возможность изменять и проверять код клиента без восстановления/перезапуска моего серверного приложения Spring. Таким образом, клиентский код не должен быть помещен в файл jar. Anyways Spring Tool Suite не создает файл jar вообще (по крайней мере для текущей конфигурации)
- Чтобы иметь возможность тестировать мое серверное приложение Spring с клиентским кодом, легко переключаться между выводами Spring Tool Suite и gradle. Таким образом, клиентский код должен быть доступен как из серверного приложения в подкаталоге
build
(фактическиbuild\libs
), так и в серверном приложении в каталогеbin
. - Когда я изменяю код клиента, он должен быть немедленно доступен для веб-браузера. Поэтому браузер не должен кэшировать его на неопределенный срок и всегда должен запрашивать обновление сервера.
- При развертывании клиентский код должен быть модифицируемым без восстановления/перезапуска серверного приложения. Таким образом, клиентский код не должен быть помещен в файл jar.
Относительно проблемы с кешем:
Без setCachePeriod (0) в addResourceHandlers() Google Chrome кэширует файл неограниченно, не запрашивая сервер для обновлений. Он даже не подключается к серверу. (Инженеры Google говорят, что поведение верное.) Итак, все, что я могу сделать, это вручную очистить кеш браузера. Это разочаровывает среду разработки и неприемлемо в производственной среде.
BTW, express.js модуль на Node.js дает разумный HTTP-заголовок по умолчанию, чтобы Google Chrome запрашивал у сервера обновления. Когда я просмотрел заголовки HTTP, которые Spring и express.js производит с использованием Fiddler, они были разными.
Любое предложение по улучшению моей среды будет оценено. Поскольку я новичок Spring, возможно, что-то не хватает.
UPDATE
Наконец, у меня есть рабочий код. Это выглядит так:
@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;
}
}
Обратите внимание на имена bean. Я добавил "мой", чтобы избежать столкновения имен.
Сам контекст приложения Autowiring кажется неудобным, но для обработки кода в org.springframework.web.servlet.config.annotation.ResourceHandlerRegistration.addResourceLocations()
необходимо было.
Теперь у меня есть обработчик favicon без проблемы кэширования, и я могу разместить файл favicon в любом месте.
Спасибо.