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.
classpath:/static
jede weitere zum Beispiel). (Deshalb ist die Favicon-Unterstützung in Boot in einem eigenen HandlerMapping, denke ich.)