Wie kann ich das Favicon von Spring Boot überschreiben?
HINWEIS : Hier ist meine andere Frage, die eine andere Lösung bietet, die keine Codierung beinhaltet: Spring Boot: Ist es möglich, externe application.properties-Dateien in beliebigen Verzeichnissen mit einem fetten Glas zu verwenden? Es ist für application.properties, kann aber auch auf das Favicon angewendet werden. Tatsächlich verwende ich diese Methode jetzt zum Überschreiben von Favicon.
Wenn ich eine Klasse mit @EnableWebMvc implementiere, wird die WebMvcAutoConfiguration-Klasse von Spring Boot nicht geladen, und ich kann mein eigenes Favicon bereitstellen, indem ich es in das Stammverzeichnis des statischen Inhalts lege.
Andernfalls registriert WebMvcAutoConfiguration die Bean faviconRequestHandler (siehe Quelle https://github.com/spring-projects/spring-boot/blob/master/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/). web / WebMvcAutoConfiguration.java ) und es dient das Symbol 'grünes Blatt', das sich im Hauptressourcenverzeichnis des Spring Boot befindet.
Wie kann ich es überschreiben, ohne selbst eine Klasse mit @EnableWebMvc zu implementieren, wodurch die gesamte Standardkonfigurationsfunktionalität der WebMvcAutoConfiguration-Klasse von Spring Boot deaktiviert wird?
Da ich möchte, dass die Symboldatei auf der Client-Seite (Webbrowser) so schnell wie möglich aktualisiert wird, möchte ich den Cache-Zeitraum der Favicon-Datei auf 0 setzen (wie den folgenden Code, den ich für meine verwende 'statische' Webapp-Inhalte und Skriptdateien, die auf der Clientseite so schnell wie möglich aktualisiert werden müssen, nachdem ich die Datei geändert habe.)
public void addResourceHandlers(ResourceHandlerRegistry registry)
{
registry.addResourceHandler("/**")
.addResourceLocations("/")
.setCachePeriod(0);
}
Nur um den Speicherort für die Datei favicon.ico zu finden, reicht die faviconRequestHandler-Auszeichnung von Spring Boot möglicherweise nicht aus.
AKTUALISIEREN
Jetzt weiß ich, dass ich die Standarddatei überschreiben kann, indem ich eine Favicon-Datei im Verzeichnis src / main / resources ablege. Das Problem der Cache-Periode bleibt jedoch bestehen.
Außerdem ist es vorzuziehen, die Favicon-Datei in das Verzeichnis zu legen, in dem statische Webdateien abgelegt werden, und nicht in das Ressourcenverzeichnis.
AKTUALISIEREN
Ok, ich habe es geschafft, die Standardeinstellung zu überschreiben. Was ich getan habe ist wie folgt:
@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);
}
}
}
Grundsätzlich habe ich den Standard überschrieben, indem ich einen Ressourcenhandler mit der höchsten Ordnung hinzugefügt habe, indem ich registry.setOrder (Integer.MIN_VALUE) aufgerufen habe.
Da der Standardwert in Spring Boot den Bestellwert (Integer.MIN_VALUE + 1) hat (siehe FaviconConfiguration-Klasse unter https://github.com/spring-projects/spring-boot/blob/master/spring-boot-autoconfigure/). src / main / java / org / springframework / boot / autoconfigure / web / WebMvcAutoConfiguration.java ) Mein Handler gewinnt.
Ist das ok? Gibt es einen anderen Weg (etwas Sanfteres als das, was ich getan habe)?
AKTUALISIEREN
Es ist nicht okay. Wenn ich anrufe registry.setOrder(Integer.MIN_VALUE)
, erhöhe ich tatsächlich die Priorität aller Ressourcenhandler. Wenn ich also folgenden Code zu einem anderen hinzufüge WebMvcConfigurerAdapter
, werden effektiv alle http-Anforderungen an diesen Ressourcenhandler gerichtet, wodurch jegliche dynamische Behandlung durch Java-Code verhindert wird.
public void addResourceHandlers(ResourceHandlerRegistry registry)
{
registry.addResourceHandler("/**")
.addResourceLocations("/")
.setCachePeriod(0);
}
Eine andere Lösung ist erforderlich.
AKTUALISIEREN
Im Moment konnte ich die Favicon-Funktionalität von Spring Boot nicht überschreiben.
Vielleicht gibt es eine Möglichkeit, meine eigene HandlerMapping
Bohne hinzuzufügen , aber ich weiß nicht, wie ich das machen soll.
Jetzt kann ich eine der folgenden Optionen auswählen:
- Haben Sie eine Klasse, die
@EnableWebMvc
somit die Spring Boot-WebMvcAutoConfiguration
Klasse deaktiviert . (Ich kann denWebMvcAutoConfiguration
Klassencode kopieren und die Favicon-Funktionalität löschen.) - Geben Sie die Freiheit auf, Favicon-Dateien an einem beliebigen Speicherort abzulegen, und legen Sie sie im Ressourcenverzeichnis ab, wie es die Favicon-Funktionalität von Spring Boot erfordert. Und ignorieren Sie das Caching-Problem.
Aber keine Option ist zufriedenstellend.
Ich möchte nur die Favicon-Datei in meine statischen Webdateien einfügen (dies kann ein beliebiges Verzeichnis sein, da ich den Dokumentstamm ändern kann) und das Caching-Problem beheben.
Vermisse ich etwas
Jeder Vorschlag wäre sehr dankbar.
AKTUALISIEREN
Übrigens, der Grund, warum ich den Speicherort von Favicon und anderen statischen Dateien ändern möchte, ist folgender. Im Moment geht es hauptsächlich um die Entwicklungsumgebung.
Ich erstelle eine Single Page Web Application (SPA).
Bibliotheken / Frameworks:
- Für die Serverseite verwende ich Spring. (natürlich)
- Für die Client-Seite (Webbrowser) verwende ich AngularJS.
Werkzeuge:
- Für die Serverseite verwende ich Spring Tool Suite.
- Für die Client-Seite verwende ich WebStorm.
Hauptverzeichnisstruktur:
ProjectRoot\
src\
bin\
build\
webapp\
build.gradle
- src: Wo sich meine Spring Java-Quelldateien befinden.
- bin: Wo Spring Tool Suite seine Build-Ausgabe platziert.
- build: Wo 'gradle build' seine Build-Ausgabe platziert.
- webapp: Wo sich meine Client-Quelldateien (.js, .css, .htm und favicon) befinden. Dies ist also das WebStorm-Projektverzeichnis. (Ich kann den Verzeichnisnamen bei Bedarf ändern)
Was ich will ist:
- Um meinen Client-Code ändern und testen zu können, ohne meine Spring Server-Anwendung neu zu erstellen / neu zu starten. Der Client-Code darf also nicht in die JAR-Datei eingefügt werden. Wie auch immer, Spring Tool Suite erstellt überhaupt keine JAR-Datei (zumindest für die aktuelle Konfiguration)
- Um meine Spring Server-Anwendung mit dem Client-Code testen zu können, können Sie problemlos zwischen der Spring Tool Suite-Ausgabe und der Gradle-Ausgabe wechseln. Daher muss auf den Clientcode sowohl von der Serveranwendung im
build
Unterverzeichnis (tatsächlichbuild\libs
) als auch von der Serveranwendung imbin
Verzeichnis aus zugegriffen werden können . - Wenn ich den Client-Code ändere, muss er dem Webbrowser sofort zur Verfügung stehen. Der Browser darf es also nicht auf unbestimmte Zeit zwischenspeichern und muss immer nach dem Server für die Aktualisierung fragen.
- Bei der Bereitstellung muss der Clientcode geändert werden können, ohne dass die Serveranwendung neu erstellt / neu gestartet werden muss. Der Client-Code darf also nicht in die JAR-Datei eingefügt werden.
In Bezug auf das Cache-Problem:
Ohne setCachePeriod (0) in addResourceHandlers () speichert Google Chrome die Datei auf unbestimmte Zeit zwischen, ohne den Server nach Updates zu fragen. Es wird nicht einmal eine Verbindung zum Server hergestellt. (Google-Ingenieure sagen, dass das Verhalten korrekt ist.) Ich kann also nur den Browser-Cache manuell leeren. Dies ist in der Entwicklungsumgebung frustrierend und in der Produktionsumgebung nicht akzeptabel.
Übrigens gibt das express.js-Modul auf Node.js einen angemessenen Standard-HTTP-Header an, sodass Google Chrome den Server nach Updates fragt. Als ich die HTTP-Header überprüfte, die Spring und express.js mit Fiddler erstellen, waren sie unterschiedlich.
Jeder Vorschlag zur Verbesserung meiner Umgebung wäre willkommen.
Da ich ein Frühlingsanfänger bin, fehlt mir möglicherweise etwas.
AKTUALISIEREN
Endlich habe ich einen Arbeitscode. Es ist wie folgt:
@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;
}
}
Beachten Sie die Bean-Namen. Ich habe 'my' hinzugefügt, um Namenskonflikte zu vermeiden.
Der Autowiring-Anwendungskontext selbst scheint umständlich zu sein, war jedoch für die Nachahmung des Codes erforderlich org.springframework.web.servlet.config.annotation.ResourceHandlerRegistration.addResourceLocations()
.
Jetzt habe ich einen Favicon-Handler ohne Caching-Probleme und kann die Favicon-Datei an einer beliebigen Stelle platzieren.
Vielen Dank.
quelle
classpath:/static
jede weitere zum Beispiel). (Deshalb ist die Favicon-Unterstützung in Boot in einem eigenen HandlerMapping, denke ich.)HandlerMapping
benötigt.HandlerMapping
?HandlerMapping
(kopieren Sie einfach die von Boot und geben Sie ihr eine höhere Priorität). Ich bin mir nicht sicher, warum Sie sich für den Standort des interessieren würden,favicon.ico file
aber wir können ihn konfigurierbar machen, wenn Sie möchten . Alle Browser werden es ebenfalls zwischenspeichern, daher bezweifle ich, dass die Cache-Einstellungen wichtig sind, bin aber froh, dass ich mich als falsch erwiesen habe.Antworten:
Sie können einfach Ihre eigene favicon.ico in das Stammverzeichnis des Klassenpfads oder in einen der statischen Ressourcenpositionen (z
classpath:/static
. B. ) einfügen . Sie können die Favicon-Auflösung auch mit einem einzigen Flag vollständig deaktivierenspring.mvc.favicon.enabled=false
.Um die vollständige Kontrolle zu übernehmen, können Sie ein HandlerMapping hinzufügen (kopieren Sie einfach das von Boot und geben Sie ihm eine höhere Priorität), z
@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; } }
quelle
@Configuration
Anmerkung verpasst . Übrigens habe ich den Grund geschrieben, warum ich statische Dateien an einem anderen Ort auf der Frage platzieren möchte.faviconHandlerMapping
,requestMappingHandlerMapping
,viewControllerHandlerMapping
,beanNameHandlerMapping
,resourceHandlerMapping
,defaultServletHandlerMapping
,endpointHandlerMapping
} Also ich diese Namen müssen vermeiden.Nichts davon war für mich notwendig.
Warum sollten Sie die Standardeinstellung überschreiben, wenn Sie eine Ressource mit der generierten JAR bündeln können, die eine höhere Priorität als die Standard-JAR hat?
Um eine benutzerdefinierte
favicon.ico
Datei zu erstellen, habe ich einsrc/main/resources
Verzeichnis für meine Anwendung erstellt und diefavicon.ico
Datei dort kopiert . Die Dateien in diesem Ressourcenverzeichnis werden in das Stammverzeichnis der kompilierten JAR verschoben. Daher wird Ihre benutzerdefinierte Dateifavicon.ico
vor der von Spring bereitgestellten Datei gefunden.Wenn Sie dies tun, erzielen Sie den gleichen Effekt wie bei Ihrer oben aktualisierten Lösung.
Beachten Sie, dass Sie seit Version 1.2.0 die Datei auch einfügen können
src/main/resources/static
.quelle
src/main/resources/static/images
favicon.ico
static
Ich mag Springboot wirklich, weil es insgesamt voller intelligenter Lösungen ist, aber ich lehne es ab, eine Application Bean zu registrieren, um ein Favicon bereitzustellen, weil das einfach nur dumm ist.
Ich habe gerade meinen eigenen Favicon-Link in meinen HTML-Seitenkopf eingefügt.
<link rel="icon" type="image/png" href="images/fav.png">
Dann habe ich mein Favicon umbenannt und bei platziert
<ProjFolder>/src/main/resources/static/images/fav.png
Jetzt habe ich ein Symbol in den Browser-Registerkarten von Chrome und Firefox und in der Safari-Adressleiste, ohne Spring und Java verwenden zu müssen, und ich sollte keine Änderungen an Springboot in neueren Versionen verfolgen müssen, um solch triviale Funktionen zu erhalten.
quelle
Seit Spring Boot 1.2.2 und 1.1.11 können Sie das Standard-Favicon mithilfe der
spring.mvc.favicon.enabled = false
Eigenschaft einfach deaktivieren .Weitere Informationen finden Sie unter:
UPDATE:
spring.mvc.favicon.enabled
Seit Spring Boot 2.2.x gibt es keine Eigenschaft mehrquelle
Mit neueren Versionen von Boot (1.2 sicher, aber vielleicht auch 1.1.8) können Sie einfach eine favicon.ico in Ihre statischen Ressourcen einfügen.
quelle
Ich habe viele Optionen / Varianten ausprobiert, aber nur das hat funktioniert. (Spring Boot 2.2.7)
Favicon.ico Dateien & robots.txt in / 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(); } }
und
@Configuration @EnableWebMvc public class MvcConfig implements WebMvcConfigurer { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler( "/favicon.ico", "/robots.txt") .addResourceLocations( "classpath:/static/"); } }
Wenn es hilft, gefällt es bitte;)
quelle
registry.addResourceHandler ("/ robots.txt"). addResourceLocations ("/");
registry.addResourceHandler ("/ favicon.ico"). addResourceLocations ("/");
robots.txt, Speicherort der Datei favicon.ico: / src / main / resources
Ich habe Spring Boot 1.2.1 verwendet
quelle