如何覆盖Spring Boot的图标?
注意:这是我的另一个问题,它提供了另一个不涉及任何编码的解决方案:Spring Boot:是否可以在胖jar的任意目录中使用外部application.properties文件?它适用于application.properties,但也可以应用于favicon . 事实上,我现在正在使用该方法进行favicon覆盖 .
如果我实现了一个具有@EnableWebMvc的类,则Spring Boot的WebMvcAutoConfiguration类不会加载,我可以通过将它放在静态内容的根目录中来提供我自己的favicon .
否则,WebMvcAutoConfiguration会注册faviconRequestHandler bean(请参阅source https://github.com/spring-projects/spring-boot/blob/master/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration.java),它会提供放置在Spring Boot主资源目录中的'green leaf'图标 .
如何在不实现自己拥有@EnableWebMvc的类的情况下覆盖它,从而禁用Spring Boot的WebMvcAutoConfiguration类的整个默认配置功能?
此外,由于我希望在客户端(Web浏览器)端尽快更新图标文件,我想将favicon文件的缓存周期设置为0.(如下面的代码,我用于我的'static'webapp内容和脚本文件,我必须在更改文件后尽快在客户端更新 . )
public void addResourceHandlers(ResourceHandlerRegistry registry)
{
registry.addResourceHandler("/**")
.addResourceLocations("/")
.setCachePeriod(0);
}
所以,只是找到保存favicon.ico文件的地方,Spring Boot的faviconRequestHandler荣誉可能还不够 .
UPDATE
现在我知道我可以通过将一个favicon文件放到src / main / resources目录来覆盖默认值 . 但缓存期问题仍然存在 .
此外,最好将favicon文件放在放置静态Web文件的目录中,而不是放在资源目录中 .
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),(参见https://github.com/spring-projects/spring-boot/blob/master/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration.java中的FaviconConfiguration类)我的处理程序获胜 .
这个可以吗?还有另一种方式(比我做的更温和)?
UPDATE
这不好 . 当我调用 registry.setOrder(Integer.MIN_VALUE)
时,实际上我提高了所有资源处理程序的优先级 . 因此,当我将以下代码添加到另一个 WebMvcConfigurerAdapter
时,实际上所有http请求都被定向到该资源处理程序,从而阻止了Java代码的任何动态处理 .
public void addResourceHandlers(ResourceHandlerRegistry registry)
{
registry.addResourceHandler("/**")
.addResourceLocations("/")
.setCachePeriod(0);
}
需要另一种解决方案 .
UPDATE
目前,我找不到覆盖Spring Boot提供的favicon功能的方法 .
也许有一种方法可以添加我自己的 HandlerMapping
bean,但我不知道怎么做 .
现在我可以选择以下选项之一:
-
有一个具有
@EnableWebMvc
的类因此禁用Spring BootWebMvcAutoConfiguration
类 . (我可以复制WebMvcAutoConfiguration
类的代码并删除favicon功能) -
放弃将favicon文件放置到仲裁位置的自由,并将其放置到Spring Boot的favicon功能所需的资源目录中 . 并忽略缓存问题 .
但两种选择都不令人满意 .
我只想将favicon文件放在我的静态Web文件(可以是任何目录,因为我可以更改文档根目录)并解决缓存问题 .
我错过了什么吗?
任何建议将不胜感激 .
UPDATE
顺便说一句,我想更改favicon和其他静态文件的位置的原因如下 . 目前主要是开发环境问题 .
我正在构建一个单页Web应用程序(SPA) .
库/框架:
-
对于服务器端,我使用Spring . (当然)
-
对于客户端(Web浏览器)方面,我使用AngularJS .
工具:
-
对于服务器端,我使用Spring Tool Suite .
-
对于客户端,我使用WebStorm .
主目录结构:
ProjectRoot\
src\
bin\
build\
webapp\
build.gradle
-
src:我的Spring java源文件所在的位置 .
-
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
目录中的服务器应用程序访问客户端代码 . -
当我修改客户端代码时,它必须立即可供Web浏览器使用 . 所以浏览器不能无限期地缓存它,并且必须始终要求它服务器进行更新 .
-
部署后,客户端代码必须可修改,无需重建/重新启动服务器应用程序 . 因此不能将客户端代码放入jar文件中 .
关于缓存问题:
如果没有addResourceHandlers()上的setCachePeriod(0),Google Chrome会无限期地缓存该文件,而不会要求服务器进行更新 . 它甚至没有连接到服务器 . (Google工程师说行为是正确的 . )因此,我所能做的就是手动清除浏览器缓存 . 它对开发环境感到沮丧,对 生产环境 环境不可接受 .
BTW,Node.js上的express.js模块提供合理的默认HTTP标头,以便Google Chrome向服务器请求更新 . 当我查看Spring和express.js使用Fiddler生成的HTTP头时,它们是不同的 .
任何改善我的环境的建议都将受到赞赏 .
由于我是 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名称 . 我添加了'my'以避免名称冲突 .
自动装配应用程序上下文本身似乎很尴尬,但是在 org.springframework.web.servlet.config.annotation.ResourceHandlerRegistration.addResourceLocations()
中模仿代码是必要的 .
现在我有一个没有缓存问题的favicon处理程序,我可以将favicon文件放在我想要的任何地方 .
谢谢 .
6 回答
您可以将自己的favicon.ico放在类路径的根目录中或任何静态资源位置(例如
classpath:/static
) . 您还可以使用单个标志spring.mvc.favicon.enabled=false
完全禁用favicon分辨率 .或者为了完全控制,你可以添加一个HandlerMapping(只需从Boot中复制一个并给它一个更高的优先级),例如
这对我来说都不是必需的 .
当您可以使用生成的JAR捆绑资源时,为什么要覆盖默认值,该JAR的优先级高于默认值 .
为了实现自定义
favicon.ico
文件,我为我的应用程序创建了一个src/main/resources
目录,然后将favicon.ico
文件复制到那里 . 此资源目录中的文件将移动到已编译的JAR的根目录,因此您的自定义favicon.ico
会在Spring提供之前找到 .执行上述操作可获得与上述更新解决方案相同的效果 .
请注意,从v1.2.0开始,您也可以将文件放在
src/main/resources/static
中 .我真的很喜欢Springboot,因为整体而言它充满了智能解决方案,但我拒绝注册一个应用程序bean来提供一个favicon,因为这只是简单的愚蠢 .
我只是在我的html页面中添加了我自己的favicon链接 .
然后我重新命名了我的图标并将其放置在
现在我在Chrome和Firefox浏览器选项卡和Safari地址栏中都有一个图标,而不必使用Spring和Java,我不应该在新版本中追求对Springboot的更改以获得这些简单的功能 .
从Spring Boot 1.2.2和1.1.11开始,您可以使用
spring.mvc.favicon.enabled = false
属性轻松禁用默认的favicon .欲了解更多信息,请访问:
https://spring.io/blog/2015/02/27/spring-boot-1-2-2-released
https://spring.io/blog/2015/02/27/spring-boot-1-1-11-released
较新版本的Boot(肯定是1.2但也可能是1.1.8)允许您只在您的静态资源中放置一个favicon.ico .
. registry.addResourceHandler( “/ robots.txt的”)addResourceLocations( “/”);
. registry.addResourceHandler( “/的favicon.ico”)addResourceLocations( “/”);
robots.txt,favicon.ico文件位置:/ src / main / resources
我用的是 Spring 季靴子1.2.1