Spring Boot:覆盖图标

zeo*_*dtr 75 favicon spring-mvc spring-boot

如何覆盖Spring Boot的图标?

注意:这是我的另一个问题,它提供了另一个不涉及任何编码的解决方案:Spring Boot:是否可以在胖jar的任意目录中使用外部application.properties文件?它适用于application.properties,但也可以应用于favicon.事实上,我现在正在使用该方法进行favicon覆盖.

如果我实现了一个具有@EnableWebMvc的类,则不会加载Spring Boot的WebMvcAutoConfiguration类,并且我可以通过将其放置到静态内容的根目录来提供我自己的favicon.

否则,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浏览器)端尽快更新图标文件,我想将favicon文件的缓存周期设置为0.(如下面的代码,我用于我的'static'webapp内容和脚本文件,我必须在更改文件后尽快在客户端更新.)

public void addResourceHandlers(ResourceHandlerRegistry registry)
{
    registry.addResourceHandler("/**")
        .addResourceLocations("/")
        .setCachePeriod(0);
}
Run Code Online (Sandbox Code Playgroud)

因此,只是找到保存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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

基本上,我通过调用registry.setOrder(Integer.MIN_VALUE)来添加具有最高顺序的资源处理程序来覆盖默认值.

由于Spring Boot中的默认值具有订单值(Integer.MIN_VALUE + 1),(请参阅https://github.com/spring-projects/spring-boot/blob/master/spring-boot-autoconfigure/中的 FaviconConfiguration类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);
}
Run Code Online (Sandbox Code Playgroud)

需要另一种解决方案.

UPDATE

目前,我找不到覆盖Spring Boot提供的favicon功能的方法.
也许有一种方法可以添加添加我自己的HandlerMappingbean,但我不知道该怎么做.

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

  1. 有一个类@EnableWebMvc因此禁用Spring Boot WebMvcAutoConfiguration类.(我可以复制WebMvcAutoConfiguration类的代码并删除favicon功能)
  2. 放弃将favicon文件放置到仲裁位置的自由,并将其放置到Spring Boot的favicon功能所需的资源目录中.并忽略缓存问题.

但两种选择都不令人满意.
我只想将favicon文件放在我的静态Web文件(可以是任何目录,因为我可以更改文档根目录)并解决缓存问题.
我错过了什么吗?
任何建议将不胜感激.

UPDATE

顺便说一句,我想更改favicon和其他静态文件的位置的原因如下.目前主要是开发环境问题.

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

库/框架:

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

工具:

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

主目录结构:

ProjectRoot\
    src\
    bin\
    build\
    webapp\
    build.gradle
Run Code Online (Sandbox Code Playgroud)
  • 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头时,它们是不同的.

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

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

注意bean名称.我添加了'my'以避免名字冲突.
自动装配应用程序上下文本身似乎很尴尬,但它是模拟代码所必需的org.springframework.web.servlet.config.annotation.ResourceHandlerRegistration.addResourceLocations().

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

Ros*_*oss 73

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

当您可以使用生成的JAR捆绑资源时,为什么要覆盖默认值,该JAR的优先级高于默认值.

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

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

请注意,从v1.2.0开始,您也可以将文件放入src/main/resources/static.

  • 原因很简单.我不想将favicon文件放入JAR中. (6认同)

Dav*_*yer 50

您可以将自己的favicon.ico放在类路径的根目录中或任何静态资源位置(例如classpath:/static)中.您还可以使用单个标志完全禁用favicon分辨率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;
}
}
Run Code Online (Sandbox Code Playgroud)

  • 您应该阅读更新的答案以及用户指南.如果您只想更改图标,那么这绝不是一个非常困难的变化.我不知道OP为什么会这么麻烦. (2认同)

jer*_*own 26

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

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

<link rel="icon" type="image/png" href="images/fav.png">
Run Code Online (Sandbox Code Playgroud)

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

<ProjFolder>/src/main/resources/static/images/fav.png
Run Code Online (Sandbox Code Playgroud)

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

  • 您不必再处理处理程序映射(只需在您的静态资源中放置一个favicon.ico). (3认同)

Try*_*usz 13

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

欲了解更多信息,请访问: