wake-up-neo.com

Spring Boot: Übergeordnetes Favicon

Wie kann ich das Favicon von Spring Boot überschreiben?

[~ # ~] note [~ # ~] : Hier ist meine andere Frage, die eine andere Lösung bietet, die keine Kodierung beinhaltet: Spring Boot: Ist es möglich, externe application.properties-Dateien in beliebigen Verzeichnissen mit einem Fat Jar 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 Favicons.

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 wird das 'green leaf'-Symbol angezeigt, das sich im Hauptressourcenverzeichnis von Spring Boot befindet.

Wie kann ich es überschreiben, ohne eine Klasse mit @EnableWebMvc selbst 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 (im 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 Ort zu finden, an dem die Datei favicon.ico gespeichert werden soll, reicht die faviconRequestHandler-Auszeichnung von Spring Boot möglicherweise nicht aus.

[~ # ~] Update [~ # ~]

Jetzt weiß ich, dass ich die Standarddatei überschreiben kann, indem ich eine Favicon-Datei in das Verzeichnis src/main/resources lege. Das Problem mit der Cache-Zeit bleibt jedoch bestehen.
Außerdem ist es vorzuziehen, die Favicon-Datei in dem Verzeichnis abzulegen, in dem statische Webdateien gespeichert sind, und nicht in dem Ressourcenverzeichnis.

[~ # ~] Update [~ # ~]

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 die Standardeinstellung überschrieben, indem ich einen Ressourcen-Handler mit der höchsten Ordnung hinzugefügt habe, indem ich registry.setOrder (Integer.MIN_VALUE) aufgerufen habe.

Da die Standardeinstellung in Spring Boot den Bestellwert (Integer.MIN_VALUE + 1) hat (siehe FaviconConfiguration-Klasse in 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)?

[~ # ~] Update [~ # ~]

Es ist nicht okay. Wenn ich registry.setOrder(Integer.MIN_VALUE) aufrufe, erhöhe ich tatsächlich die Priorität aller Ressourcen-Handler. Wenn ich also folgenden Code zu einem anderen WebMvcConfigurerAdapter hinzufüge, werden alle http-Anforderungen an diesen Ressourcenhandler weitergeleitet, wodurch jede dynamische Verarbeitung durch Java Code verhindert wird.

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

Eine andere Lösung ist erforderlich.

[~ # ~] Update [~ # ~]

Im Moment konnte ich den Weg nicht finden, die von Spring Boot bereitgestellte Favicon-Funktionalität zu überschreiben.
Vielleicht gibt es eine Möglichkeit, meine eigene HandlerMapping Bean hinzuzufügen, aber ich weiß nicht, wie ich das machen soll.

Jetzt kann ich eine der folgenden Optionen auswählen:

  1. Haben Sie eine Klasse mit @EnableWebMvc, Wodurch Spring Boot WebMvcAutoConfiguration class deaktiviert wird. (Ich kann den Code der Klasse WebMvcAutoConfiguration kopieren und die Favicon-Funktionalität löschen.)
  2. Geben Sie die Freiheit auf, die Favicon-Datei an einem beliebigen Ort abzulegen, und legen Sie sie im Ressourcenverzeichnis ab, wie es die Favicon-Funktionalität von Spring Boot erfordert. Und Cache-Problem ignorieren.

Aber keine Option ist zufriedenstellend.
Ich möchte nur die Favicon-Datei mit meinen statischen Webdateien (die jedes Verzeichnis sein können, da ich den Dokumentenstamm ändern kann) platzieren und das Caching-Problem beheben.
Vermisse ich etwas?
Jeder Vorschlag wäre sehr dankbar.

[~ # ~] Update [~ # ~]

Ü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 einseitige Webanwendung (SPA).

Bibliotheken/Frameworks:

  • Für die Serverseite verwende ich Spring. (Na sicher)
  • 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 befinden sich meine Quelldateien für Spring Java?.
  • bin: Hier platziert Spring Tool Suite die Build-Ausgabe.
  • build: Wo 'gradle build' seine Build-Ausgabe platziert.
  • webapp: Wo befinden sich meine Client-Quelldateien (.js, .css, .htm und favicon)? Dies ist also das WebStorm-Projektverzeichnis. (Ich kann den Verzeichnisnamen bei Bedarf ändern)

Was ich will ist:

  • So können Sie meinen Clientcode ändern und testen, ohne meine Spring-Serveranwendung neu erstellen oder neu starten zu müssen. Der Client-Code darf also nicht in die JAR-Datei eingefügt werden. Trotzdem erstellt Spring Tool Suite überhaupt keine JAR-Datei (zumindest für die aktuelle Konfiguration)
  • Um meine Spring-Server-Anwendung mit dem Client-Code zu testen, können Sie einfach zwischen der Ausgabe der Spring Tool Suite und der Gradle-Ausgabe wechseln. Daher muss der Zugriff auf den Clientcode sowohl über die Serveranwendung im Unterverzeichnis build (tatsächlich build\libs) Als auch über die Serveranwendung im Verzeichnis bin erfolgen.
  • Wenn ich den Clientcode ändere, muss er sofort für den Webbrowser verfügbar sein. Der Browser darf ihn also nicht auf unbestimmte Zeit zwischenspeichern und muss immer nach dem Server fragen, um ihn zu aktualisieren.
  • Bei der Bereitstellung muss der Clientcode ohne Neuerstellung/Neustart der Serveranwendung geändert werden können. Der Client-Code darf also nicht in die JAR-Datei eingefügt werden.

In Bezug auf das Cache-Problem:

Ohne setCachePeriod (0) auf addResourceHandlers () speichert Google Chrome die Datei unbegrenzt im Cache, ohne den Server nach Updates zu fragen. Es wird nicht einmal eine Verbindung zum Server hergestellt. (Google-Ingenieure sagen, dass das Verhalten korrekt ist.) Alles, was ich tun kann, ist, den Browser-Cache manuell zu leeren. Dies ist in der Entwicklungsumgebung frustrierend und in der Produktionsumgebung nicht akzeptabel.

Übrigens: Das Modul express.js in Node.js gibt einen angemessenen HTTP-Standardheader 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, kann mir etwas fehlen.

[~ # ~] Update [~ # ~]

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.
Autowiring-Anwendungskontext selbst scheint umständlich zu sein, er war jedoch erforderlich, um den Code in org.springframework.web.servlet.config.annotation.ResourceHandlerRegistration.addResourceLocations() nachzuahmen.

Jetzt habe ich einen Favicon-Handler ohne Caching-Probleme und kann die Favicon-Datei an einer beliebigen Stelle ablegen.
Vielen Dank.

75
zeodtr

Sie können einfach Ihre eigene Datei favicon.ico im Stammverzeichnis des Klassenpfads oder an einem beliebigen statischen Speicherort der Ressource ablegen (z. B. classpath:/static). Sie können die Favicon-Auflösung auch vollständig deaktivieren, indem Sie ein einzelnes Flag spring.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;
}
}
49
Dave Syer

Nichts davon war für mich notwendig.

Warum den Standard überschreiben, wenn Sie eine Ressource mit der generierten JAR-Datei bündeln können, die eine höhere Priorität als die Standard-JAR-Datei hat?.

Um eine benutzerdefinierte favicon.ico - Datei zu erstellen, habe ich ein src/main/resources - Verzeichnis für meine Anwendung erstellt und dann die favicon.ico - Datei dorthin kopiert. Die Dateien in diesem Ressourcenverzeichnis werden in das Stammverzeichnis der kompilierten JAR verschoben, und daher wird Ihre benutzerdefinierte favicon.ico Gefunden, bevor die von Spring bereitgestellte vorhanden ist.

Wenn Sie dies tun, erzielen Sie den gleichen Effekt wie bei Ihrer aktualisierten Lösung oben.

Beachten Sie, dass Sie die Datei seit Version 1.2.0 auch in src/main/resources/static Ablegen können.

73
Ross

Ich mag Springboot wirklich, weil es insgesamt voller intelligenter Lösungen ist, aber ich weigere mich, eine Application Bean zu registrieren, um ein Favicon bereitzustellen, weil das einfach nur dumm ist.

Ich habe soeben meinen eigenen Favicon-Link in meinen HTML-Kopf eingefügt.

<link rel="icon" type="image/png" href="images/fav.png">

Dann habe ich mein Favicon umbenannt und auf gelegt

<ProjFolder>/src/main/resources/static/images/fav.png

Jetzt habe ich ein Symbol in den Registerkarten Chrome und Firefox-Browser sowie in der Safari-Adressleiste, ohne Spring und Java verwenden zu müssen, und ich sollte nicht nach Änderungen an Springboot in neueren Versionen suchen müssen, um solche trivialen Funktionen zu erhalten .

26
jeremyjjbrown

Seit Spring Boot 1.2.2 und 1.1.11 können Sie das Standard-Favicon einfach mit der Eigenschaft spring.mvc.favicon.enabled = false Deaktivieren.

Für weitere Informationen besuchen Sie:

13

Neuere Versionen von Boot (mit Sicherheit 1.2, aber vielleicht auch 1.1.8) ermöglichen es Ihnen, einfach eine favicon.ico in Ihre statischen Ressourcen einzufügen.

2
Dave Syer

registry.addResourceHandler ("/ robots.txt"). addResourceLocations ("/");

registry.addResourceHandler ("/ favicon.ico"). addResourceLocations ("/");

robots.txt, favicon.ico Dateispeicherort:/src/main/resources

ich habe Spring Boot 1.2.1 verwendet

1
webmadeup