Как я могу переопределить значок 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.)HandlerMapping
нужно отдельное .HandlerMapping
?HandlerMapping
(просто скопируйте его из Boot и установите более высокий приоритет). Я не совсем уверен, почему вам нужно заботиться о местоположении,favicon.ico file
но мы можем сделать его настраиваемым, если хотите. Все браузеры также будут кэшировать его, поэтому я сомневаюсь, что настройки кеша имеют значение, но я рад, что ошибся.Ответы:
Вы можете просто поместить свой собственный favicon.ico в корень пути к классам или в любое из мест статических ресурсов (например,
classpath:/static
). Вы также можете полностью отключить разрешение значков с помощью одного флагаspring.mvc.favicon.enabled=false
.Или, чтобы получить полный контроль, вы можете добавить HandlerMapping (просто скопируйте его из Boot и назначьте ему более высокий приоритет), например
@Configuration public static class FaviconConfiguration { @Bean public SimpleUrlHandlerMapping faviconHandlerMapping() { SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping(); mapping.setOrder(Integer.MIN_VALUE); mapping.setUrlMap(Collections.singletonMap("mylocation/favicon.ico", faviconRequestHandler())); return mapping; } @Bean protected ResourceHttpRequestHandler faviconRequestHandler() { ResourceHttpRequestHandler requestHandler = new ResourceHttpRequestHandler(); requestHandler.setLocations(Arrays .<Resource> asList(new ClassPathResource("/"))); return requestHandler; } }
источник
@Configuration
аннотацию. Кстати, я написал причину, по которой я хочу разместить статические файлы в другом месте в вопросе.faviconHandlerMapping
,requestMappingHandlerMapping
,viewControllerHandlerMapping
,beanNameHandlerMapping
,resourceHandlerMapping
,defaultServletHandlerMapping
,endpointHandlerMapping
} Таким образом , я должен избегать этих имен.Мне все это было не нужно.
Зачем переопределять значение по умолчанию, если вы можете связать ресурс с сгенерированным JAR, который будет иметь более высокий приоритет, чем приоритет по умолчанию.
Чтобы создать собственный
favicon.ico
файл, я создалsrc/main/resources
каталог для своего приложения, а затем скопировал в негоfavicon.ico
файл. Файлы в этом каталоге ресурсов перемещаются в корень скомпилированного JAR, и поэтому ваш заказfavicon.ico
находится до того, как его предоставил Spring.Выполнение вышеуказанного привело к тому же эффекту, что и ваше обновленное решение, указанное выше.
Обратите внимание, что начиная с версии 1.2.0 вы также можете поместить файл в формат
src/main/resources/static
.источник
src/main/resources/static/images
favicon.ico
с помощьюstatic
: github.com/spring-projects/spring-boot/commit/…Мне очень нравится Springboot, потому что в целом он полон умных решений, но я отказываюсь регистрировать компонент приложения для предоставления значка, потому что это просто глупо.
Я просто добавил свою собственную ссылку на значок в заголовке своей html-страницы вот так.
<link rel="icon" type="image/png" href="images/fav.png">
Затем я переименовал свой значок и поместил его в
<ProjFolder>/src/main/resources/static/images/fav.png
Теперь у меня есть значок на вкладках браузера Chrome и Firefox и в адресной строке Safari без использования Spring и Java, и мне не придется гнаться за изменениями Springboot в новых версиях для такой тривиальной функциональности.
источник
Начиная с Spring Boot 1.2.2 и 1.1.11 вы можете легко отключить значок по умолчанию, используя
spring.mvc.favicon.enabled = false
свойство.Для получения дополнительной информации посетите:
ОБНОВЛЕНИЕ:
spring.mvc.favicon.enabled
свойство больше не существует с Spring Boot 2.2.xисточник
Более новые версии Boot (наверняка 1.2, но, возможно, также и 1.1.8) позволяют вам просто поместить favicon.ico в ваши статические ресурсы.
источник
Я перепробовал много вариантов / вариантов, но только это сработало. (Весенняя загрузка 2.2.7)
Файлы Favicon.ico и robots.txt помещаются в / resources / static
@Configuration @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/favicon.ico").permitAll() .antMatchers("/robots.txt").permitAll() .antMatchers("/").permitAll() .anyRequest().authenticated(); } }
и
@Configuration @EnableWebMvc public class MvcConfig implements WebMvcConfigurer { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler( "/favicon.ico", "/robots.txt") .addResourceLocations( "classpath:/static/"); } }
Если поможет, пожалуйста, полюбите;)
источник
registry.addResourceHandler ("/ robots.txt"). addResourceLocations ("/");
registry.addResourceHandler ("/ favicon.ico"). addResourceLocations ("/");
robots.txt, расположение файла favicon.ico: / src / main / resources
я использовал пружинный ботинок 1.2.1
источник