Spring Boot:覆盖图标

时间:2013-12-19 04:03:24

标签: spring-mvc favicon spring-boot

如何覆盖Spring Boot的图标?

  

注意:这是我的另一个问题,提供了另一个不涉及任何编码的解决方案:Spring Boot: Is it possible to use external application.properties files in arbitrary directories with a fat jar?它适用于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的主要资源目录中。

如何在不实现自己拥有@EnableWebMvc的类的情况下覆盖它,从而禁用Spring Boot的WebMvcAutoConfiguration类的整个默认配置功能?

另外,由于我希望在客户端(Web浏览器)端尽快更新图标文件,我想将favicon文件的缓存周期设置为0.(如下面的代码,我和#39 ; m用于我的“静态”webapp内容和脚本文件,在我更改文件后,必须尽快在客户端更新。)

public void addResourceHandlers(ResourceHandlerRegistry registry)
{
    registry.addResourceHandler("/**")
        .addResourceLocations("/")
        .setCachePeriod(0);
}

所以,只是找到保存favicon.ico文件的地方,Spring Boot的faviconRequestHandler荣誉可能还不够。

更新

现在我知道我可以通过将一个favicon文件放到src / main / resources目录来覆盖默认文件。但缓存期问题仍然存在 此外,最好将favicon文件放在放置静态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提供的favicon功能的方法 也许有一种方法可以添加添加我自己的HandlerMapping bean,但我不知道该怎么做。

现在我可以选择以下选项之一:

  1. 有一个具有@EnableWebMvc的类因此禁用Spring Boot WebMvcAutoConfiguration类。 (我可以复制WebMvcAutoConfiguration类的代码并删除favicon功能)
  2. 放弃将favicon文件放置到仲裁位置的自由,并将其放置在Spring Boot的favicon功能所需的资源目录中。并忽略缓存问题。
  3. 但两种选择都不令人满意 我只想将favicon文件放在我的静态Web文件中(可以是任何目录,因为我可以更改文档根目录)并解决缓存问题。
    我错过了什么吗? 任何建议都将不胜感激。

    更新

    BTW,我想更改favicon和其他静态文件的位置的原因如下。目前主要是发展环境问题。

    我正在构建单页面Web应用程序(SPA)。

    库/框架:

    • 对于服务器端,我使用Spring。 (当然)
    • 对于客户端(Web浏览器)方面,我使用AngularJS。

    工具:

    • 对于服务器端,我使用Spring Tool Suite。
    • 对于客户端,我使用WebStorm。

    主目录结构:

    ProjectRoot\
        src\
        bin\
        build\
        webapp\
        build.gradle
    
    • src:我的Spring java源文件所在的位置。
    • bin:Spring Tool Suite放置其构建输出的位置。
    • 构建:在哪里' 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头时,它们是不同的。

    任何有关改善环境的建议都将受到赞赏 由于我是一名春季初学者,我可能会遗漏一些东西。

    更新

    最后我有一个有效的代码。它如下:

    @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名称。我添加了“我的&#39;避免姓名冲突。
    自动装配应用程序上下文本身似乎很尴尬,但是在org.springframework.web.servlet.config.annotation.ResourceHandlerRegistration.addResourceLocations()中模仿代码是必要的。

    现在我有一个没有缓存问题的favicon处理程序,我可以将favicon文件放在我想要的任何地方 感谢。

8 个答案:

答案 0 :(得分:71)

这对我来说都不是必需的。

为什么要在使用生成的JAR捆绑资源时覆盖默认值,该JAR的优先级高于默认值。

为了实现自定义favicon.ico文件,我为我的应用程序创建了一个src/main/resources目录,然后将favicon.ico文件复制到那里。此资源目录中的文件将移动到已编译的JAR的根目录,因此在Spring提供之前找到您的自定义favicon.ico

执行上述操作可获得与上述更新解决方案相同的效果。

请注意,自v1.2.0起,您还可以将文件放在src/main/resources/static

答案 1 :(得分:47)

您可以将自己的favicon.ico放在类路径的根目录中或任何静态资源位置(例如classpath:/static)。您还可以使用单个标记spring.mvc.favicon.enabled=false完全禁用favicon分辨率。

或者为了完全控制你可以添加一个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;
}
}

答案 2 :(得分:25)

我真的很喜欢Springboot,因为总体来说它充满了智能解决方案,但我拒绝注册一个应用程序bean来提供一个favicon,因为这只是简单的愚蠢。

我刚才在我的html页面中添加了我自己的favicon链接。

<link rel="icon" type="image/png" href="images/fav.png">

然后我重命名了我的图标并将其放在

<ProjFolder>/src/main/resources/static/images/fav.png

现在我在Chrome和Firefox浏览器选项卡和Safari地址栏中都有一个图标,而不必使用Spring和Java,我不应该在新版本中追求对Springboot的更改,以实现这些简单的功能。

答案 3 :(得分:13)

从Spring Boot 1.2.2和1.1.11开始,您可以使用spring.mvc.favicon.enabled = false属性轻松禁用默认图标。

有关更多信息,请访问:

答案 4 :(得分:2)

较新版本的Boot(肯定是1.2但也可能是1.1.8)允许您只在您的静态资源中放置一个favicon.ico。

答案 5 :(得分:2)

我尝试了很多选项/变体,但是只有这个可行。 (Spring Boot 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/");
  }
}

如果有帮助,请喜欢;)

答案 6 :(得分:1)

registry.addResourceHandler(&#34; /robots.txt")addResourceLocations(&#34; /&#34);

registry.addResourceHandler(&#34; /favicon.ico")addResourceLocations(&#34; /&#34);

robots.txt,favicon.ico文件位置:/ src / main / resources

我使用的是spring boot 1.2.1

答案 7 :(得分:0)

我使用的是 Spring Boot 2.5.2 版。就我而言,我只需要一个用于 favicon 的 jpg/png 文件而不是 favicon.ico 文件

将您的 favicon.jpg/favicon.png 文件放在类路径中的 resources 文件夹中 - src/main/resources/favicon.png
或在类路径中资源文件夹的 static 文件夹中 -
src/main/resources/static/favicon.png

在资源文件夹中的每个 模板文件夹 中的 HTML 页面中,放入 -
<link rel="icon" type="image/png" href="../favicon.png">

<link rel="icon" type="image/png" href="../static/favicon.png">
分别在 head 标签 内。