如何覆盖 SpringBoot 的图标?
注意 : 这是我的另一个问题,它提供了另一个不涉及任何编码的解决方案: Spring Boot: 是否可以在带有胖 jar 的任意目录中使用外部 application.properties 文件?它是用于 application.properties 的,但它也可以应用于图标。事实上,我现在正在使用这个方法来覆盖图标。
如果我实现了一个具有@EnableWebMvc 的类,那么 Spring Boot 的 WebMvcAutoConfiguration 类不会加载,我可以通过将它放置到静态内容的根目录来提供我自己的图标。
否则,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 的主资源目录中的“绿叶”图标提供服务。
如何在不实现具有@EnableWebMvc 的类的情况下覆盖它,从而禁用 Spring Boot 的 WebMvcAutoConfiguration 类的整个默认配置功能?
另外,由于我希望图标文件在客户端(web 浏览器)尽快更新,我想设置图标文件的缓存期为0。(如下面的代码,我使用的’静态’网络应用程序的内容和脚本文件,必须在客户端尽快更新后,我改变了文件。)
public void addResourceHandlers(ResourceHandlerRegistry registry)
{
registry.addResourceHandler("/**")
.addResourceLocations("/")
.setCachePeriod(0);
}
因此,仅仅为了找到一个地方来保存 Favicon.ico 文件,Spring Boot 的 FaviconRequestHandler 的优点可能是不够的。
更新
现在我知道可以通过在 src/main/resources 目录中放置一个图标文件来覆盖默认值。但是缓存期问题仍然存在。
另外,最好将图标文件放在静态 web 文件所在的目录中,而不是放在资源目录中。
更新
好的,我设法覆盖了默认的那个。 我所做的如下:
@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 类)我的处理程序胜出。
这样可以吗? 还有别的方法吗(比我做的更温和的方法) ?
更新
一点都不好。
当我调用 registry.setOrder(Integer.MIN_VALUE)
时,实际上我提高了所有资源处理程序的优先级。因此,当我将以下代码添加到另一个 WebMvcConfigurerAdapter
时,实际上所有的 http 请求都被定向到该资源处理程序,从而防止 Java 代码进行任何动态处理。
public void addResourceHandlers(ResourceHandlerRegistry registry)
{
registry.addResourceHandler("/**")
.addResourceLocations("/")
.setCachePeriod(0);
}
需要另一种解决方案。
更新
现在,我找不到覆盖 Spring Boot 提供的图标功能的方法。
也许有一种方法可以添加我自己的 HandlerMapping
bean,但我不知道如何做到这一点。
现在我可以选择以下选项之一:
@EnableWebMvc
的类,从而禁用 Spring BootWebMvcAutoConfiguration
类。(我可以复制代码的 WebMvcAutoConfiguration
类和删除图标的功能)但这两种选择都不令人满意。
我只是想把图标文件与我的静态 web 文件(可以是任何目录,因为我可以更改文档根)和解决缓存问题。
我错过了什么吗?
如有任何建议,我将不胜感激。
更新
顺便说一下,我想改变图标和其他静态文件的位置的原因如下。目前主要是发展环境问题。
我正在构建一个单页面 Web 应用程序(SPA)。
图书馆/架构:
工具:
主目录结构:
ProjectRoot\
src\
bin\
build\
webapp\
build.gradle
我想要的是:
build
子目录(实际上是 build\libs
)中的服务器应用程序和 bin
目录中的服务器应用程序访问客户机代码。关于缓存问题:
如果没有 addResourceHandlers ()上的 setCache (0) ,Google Chrome 就会无限期地缓存文件,而不会要求服务器进行更新。它甚至不连接到服务器。(谷歌工程师表示,这种行为是正确的。)所以我只能手动清除浏览器缓存。它在开发环境中是令人沮丧的,在生产环境中是不可接受的。
顺便说一句,Node.js 上的 Express.js 模块提供了合理的默认 HTTP 头,这样 Google Chrome 就可以请求服务器进行更新。当我回顾 Spring 和 Express.js 使用 Fiddler 生成的 HTTP 头时,它们是不同的。
任何改善我的环境的建议都会受到欢迎。
由于我是一个春季初学者,我可能遗漏了一些东西。
更新
最后,我有一个工作代码。它是这样的:
@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()
中的代码是必要的。
现在我有一个图标处理程序的缓存问题,我可以把图标文件的任何地方我想要的。
谢谢。