当前位置: 首页 > 知识库问答 >
问题:

Spring引导:覆盖favicon

卢嘉誉
2023-03-14

我如何覆盖Spring引导的favicon?

否则,WebMvcAutoConfiguration注册faviconRequestHandler bean(请参见源https://github.com/spring-projects/spring-boot/blob/master/spring-boot-autocigure/src/main/java/org/springframework/boot/autocigure/web/WebMvcAutoConfiguration.java)并为“绿叶”图标提供服务,该图标位于Spring boot的主资源目录中。

我如何在不实现自己具有@enableWebMVC的类的情况下重写它,从而禁用Spring Boot的WebMvcAutoConfiguration类的全部默认配置功能?

另外,由于我希望图标文件在客户端(web浏览器)上尽快更新,所以我希望将favicon文件的缓存周期设置为0。(比如下面的代码,我将其用于我的“静态”webapp内容和脚本文件,在我更改文件后,必须尽快在客户端更新这些文件。)

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

因此,仅仅找到保存Spring Boot的faviconRequestHandler所支持的Favicon.ico文件的地方可能是不够的。

更新

更新

好的,我设法覆盖了默认的。我所做的如下:

@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)添加一个具有最高顺序的资源处理程序来覆盖默认的处理程序。

不太好。当我调用registry.setOrder(integer.min_value)时,实际上我提高了所有资源处理程序的优先级。因此,当我将下面的代码添加到另一个WebMVCConfigurerAdapter中时,实际上所有http请求都指向该资源处理程序,从而防止Java代码进行任何动态处理。

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

需要另一种解决办法。

更新

  1. 具有一个具有@EnableWebMVC的类,从而禁用Spring BootWebMVCautoConfiguration类。(我可以复制WebMVCautoConfiguration类的代码并删除favicon功能)
  2. 放弃将favicon文件放置到任意位置的自由,而是按照Spring Boot的favicon功能要求将其放置到资源目录中。和忽略缓存问题。

但这两个选项都不满意。
我只想将favicon文件与我的静态web文件放在一起(可以是任何目录,因为我可以更改文档根),并解决缓存问题。
我是否遗漏了什么?
任何建议都将非常感谢。

更新

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

我正在构建一个单页web应用程序(SPA)。

库/框架:

    null
    null
ProjectRoot\
    src\
    bin\
    build\
    webapp\
    build.gradle
  • src:Spring java源文件所在的位置。
  • bin:Spring工具套件放置其生成输出的位置。
  • 生成:“gradle build”放置其生成输出的位置。
  • webapp:我的客户端源文件(.js、.css、.htm和favicon)所在的地方。因此,这是WebStorm项目目录。(如果需要,我可以更改目录名)

我想要的是:

  • 可以修改和测试客户机代码,而无需重新构建/重新启动Spring server应用程序。因此,客户机代码不能放入jar文件中。无论如何,Spring Tool Suite根本不构建jar文件(至少对于当前配置)
  • 能够用客户端代码测试我的Spring服务器应用程序,轻松地在Spring工具套件输出和gradle输出之间切换。因此,客户端代码必须可以从build子目录(实际上是build\libs)中的服务器应用程序和bin目录中的服务器应用程序访问
  • 当我修改客户端代码时,它必须立即可供web浏览器使用。因此浏览器不能无限期地缓存它,并且必须始终请求服务器更新。
  • 部署时,客户端代码必须是可修改的,而无需重新构建/重新启动服务器应用程序。因此客户端代码不能放入jar文件中。

顺便说一句,Node.js上的Express.js模块给出了合理的默认HTTP头,以便Google Chrome请求服务器更新。当我回顾Spring和Express.js使用Fiddler生成的HTTP头时,它们是不同的。

如果有任何改善环境的建议,我将不胜感激。
因为我是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;
    }
}

共有1个答案

琴修为
2023-03-14

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

或者为了完全控制,您可以添加一个HandlerMapping(只需从引导中复制一个并赋予它更高的优先级),例如。

@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;
}
}
 类似资料:
  • > 我有两个控制器(ControllerA和ControllerB) 两个控制器都调用一个服务(MyService)。 MyService调用名为MyRepository的接口,该接口有两个实现(FirstRepository和SecondRepository)。 如何可能在从ControllerA调用服务(MyService)时使用FirstRepository而在调用来自ControllerB

  • 问题内容: 我正在使用Bootstrap 3,并且有一个显示一些数据的表。在此表中,我已应用了一些JavaScript进行条件格式设置,如果满足条件,则将元素的类设置为“红色” HTML的元素如下: 我现在在文本颜色适用的奇数行上有冲突,但是背景颜色被自举程序中的以下CSS覆盖。 我该如何解决此冲突并确保红色阶级有上风? 问题答案: 您的问题很可能与特异性有关。克里斯·科耶尔(ChrisCoyie

  • 我的意图是在spring boot应用程序中有两个概要文件—开发和生产概要文件。开发概要文件只是为了覆盖生产概要文件的一些变量(比如内存中的数据库,而不是云中的数据库)。由于我预计将来会对生产概要进行一些更改,所以在开发概要中复制变量似乎不是一个解决方案。 因此,在Spring参考中,我读到应该只从引用的配置文件中添加属性。 有时,将特定于概要文件的属性添加到活动概要文件中而不是替换它们是很有用的

  • 对于Spring Boot2.1,默认情况下禁用bean重写,这是一件好事。 然而,我确实有一些测试,其中我使用mockito用模拟实例替换bean。在默认设置下,使用这种配置的测试将由于bean重写而失败。 我发现唯一有效的方法是通过应用程序属性启用bean重写: 但是,我真的希望确保测试配置的bean定义设置最小,这一点将由spring在禁用重写的情况下指出。 我正在重写的bean是 在导入到

  • 我得到了以下css规则 我希望有

  • bootstrap.css正在覆盖我的样式...我怎样才能避免这种情况发生?如何强制css首先加载?