How can I override the spring boot icon?
NOTE Here is my other question that offers another solution that does not require any coding: Spring Download: is it possible to use an external .properties application in arbitrary directories with a thick bank? This is for application.properties, but it can also be applied to the icon. In fact, I use this method to override favicon.
If I implement a class with @EnableWebMvc, the WebMvcAutoConfiguration Spring Boot class does not load, and I can serve my own icon by placing it in the root directory of the static content.
Otherwise, WebMvcAutoConfiguration registers faviconRequestHandler bean (see source https://github.com/spring-projects/spring-boot/blob/master/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autom /web/WebMvcAutoConfiguration.java ), and it serves as a green leaf icon that is placed in the Spring Boot main resource directory.
How can I override it without introducing the class itself that @EnableWebMvc has, thereby disabling all the default configuration functions for the WebMvcAutoConfiguration Spring Boot class?
In addition, since I want the icon file to be updated as soon as possible on the client side (web browser), I want to set the caching period of the favicon file to 0. (for example, the following code, which I am using my βstaticβ webapp content and script files that should be updated on the client side as soon as possible after changing the file.)
public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/**") .addResourceLocations("/") .setCachePeriod(0); }
So, just to find a place to save the favicon.ico file, that Spring Praise faviconRequestHandler download might not be enough.
UPDATE
Now I know that I can override the default by placing the favicon file in the src / main / resources directory. But the problem with the cache period still persists.
In addition, it is preferable to place the favicon file in the directory where the static web files are located, rather than the resource directory.
UPDATE
Ok, I was able to override the default value. I have done the following:
@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); } } }
Basically, I overridden the default value by adding the highest order resource handler by calling registry.setOrder (Integer.MIN_VALUE).
Since the default value in Spring Boot is of the order of (Integer.MIN_VALUE + 1), (see the FaviconConfiguration class at https://github.com/spring-projects/spring-boot/blob/master/spring-boot-autoconfigure/ src / main / java / org / springframework / boot / autoconfigure / web / WebMvcAutoConfiguration.java ) defeats my handler.
It's good? Is there any other way (something softer than what I did)?
UPDATE
This is not true. When I call registry.setOrder(Integer.MIN_VALUE) , I actually raise the priority of all resource handlers. Therefore, when I add the following code to another WebMvcConfigurerAdapter , virtually the entire HTTP request is directed to this resource handler, preventing any dynamic processing by Java code.
public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/**") .addResourceLocations("/") .setCachePeriod(0); }
Another solution is required.
UPDATE
Currently, I cannot find a way to override the favicon Spring Boot functionality. There may be a way to add add your own HandlerMapping bean, but I don't know how to do it.
Now I can choose one of the following options:
- For a class with
@EnableWebMvc , the Spring Boot WebMvcAutoConfiguration class is @EnableWebMvc in this way. (I can copy the code of the WebMvcAutoConfiguration class and remove the favicon functionality) - Give up the freedom to place the favicon file in a harsh location and put it in the resource directory as Spring for the favicon download function. And ignore the caching issue.
But none of the options is satisfactory.
I just want to host a favicon file with my static web files (which can be any directory, since I can change the document root) and solve the cache problem. Am I missing something?
Any suggestion would be greatly appreciated.
UPDATE
By the way, the reason I want to change the location of favicon and other static files is as follows. At the moment, this is mainly a development environment problem.
I am creating a single page web application (SPA).
Libraries / Frameworks:
- For the server side, I use Spring. (sure)
- For a third-party client (web browser) I use AngularJS.
Instruments:
- For the server side, I use the Spring Tool Suite.
- For the client side, I use WebStorm.
Basic directory structure:
ProjectRoot\ src\ bin\ build\ webapp\ build.gradle
- src: Where are my Spring java source files.
- bin: Where Spring Tool Suite puts its assembly output.
- build: Where 'gradle build' puts its build output.
- webapp: Where are my client source files (.js, .css, .htm and favicon). So this is the WebStorm project directory. (If necessary, I can change the name of the directory)
I want to:
- Ability to modify and verify client code without restoring / restarting my Spring server application. Therefore, client code should not be placed in a jar file. Anyways Spring Tool Suite does not create jar file at all (at least for current configuration)
- To be able to test my Spring server application with client code, it's easy to switch between Spring Tool Suite and gradle pins. Thus, the client code must be accessible both from the server application in the
build subdirectory (actually build\libs ), and in the server application in the bin . - When I change the client code, it should be immediately accessible to the web browser. Therefore, the browser should not cache it indefinitely and should always request a server update.
- When deploying, the client code must be modifiable without restoring / restarting the server application. Therefore, client code should not be placed in a jar file.
Regarding the cache problem:
Without setCachePeriod (0) in addResourceHandlers (), Google Chrome caches the file indefinitely without asking the server for updates. It does not even connect to the server. (Google engineers say that the behavior is correct.) So, all I can do is manually clear the browser cache. This disappoints the development environment and is not acceptable in a production environment.
The BTW, express.js module on Node.js provides a reasonable default HTTP header so that Google Chrome asks the update server. When I looked at the HTTP headers that Spring and express.js produces using Fiddler, they were different.
Any suggestion to improve my environment would be appreciated. Since I'm new to Spring, maybe something is missing.
UPDATE
Finally, I have working code. It looks like this:
@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; } }
Pay attention to the bean names. I added "mine" to avoid name clashes.
The Autowiring application context itself seems inconvenient, but it was necessary to process the code in org.springframework.web.servlet.config.annotation.ResourceHandlerRegistration.addResourceLocations() .
Now I have a favicon handler without a caching problem, and I can place the favicon file anywhere.
Thank.