web-dev-qa-db-fra.com

Botte de printemps: favicon annulé

Comment puis-je remplacer le favicon de Spring Boot?

[~ # ~] note [~ # ~] : Voici une autre question qui fournit une autre solution ne nécessitant aucun codage: Spring Boot: Est-il possible d'utiliser des fichiers application.properties externes dans des répertoires arbitraires avec un gros fichier jar? C'est pour application.properties, mais il peut également être appliqué au favicon. En fait, j'utilise cette méthode pour annuler les favicon maintenant.

Si j'implémente une classe ayant @EnableWebMvc, la classe WebMvcAutoConfiguration de Spring Boot ne se charge pas et je peux servir mon propre favicon en le plaçant dans le répertoire racine du contenu statique.

Sinon, WebMvcAutoConfiguration enregistre le bean faviconRequestHandler, (voir la source https://github.com/spring-projects/spring-boot/blob/master/spring-boot-autoconfigure/src/main/Java/org/springframework/). boot/autoconfigure/web/WebMvcAutoConfiguration.Java ) et sert l'icône "feuille verte" qui est placée dans le répertoire de ressources principal du Spring Boot.

Comment puis-je le remplacer sans implémenter moi-même une classe qui a @EnableWebMvc, ce qui désactive toute la fonctionnalité de configuration par défaut de la classe WebMvcAutoConfiguration de Spring Boot?

De plus, comme je souhaite que le fichier d'icône soit mis à jour dès que possible du côté client (navigateur Web), je souhaite définir la période de cache du fichier favicon sur 0. (comme le code suivant, que j'utilise pour mes Le contenu "statique" de l'application Web et les fichiers de script qui doivent être mis à jour côté client dès que possible après la modification du fichier.)

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

Donc, trouver juste l'endroit où enregistrer le fichier favicon.ico que les honneurs faviconRequestHandler de Spring Boot peut ne pas être suffisant.

[~ # ~] met à jour [~ # ~]

Maintenant, je sais que je peux remplacer celui par défaut en plaçant un fichier favicon dans le répertoire src/main/resources. Mais le problème de la période de cache reste toujours.
De plus, il est préférable de placer le fichier favicon dans le répertoire dans lequel les fichiers Web statiques sont placés, plutôt que dans le répertoire de ressources.

[~ # ~] met à jour [~ # ~]

Ok, j'ai réussi à remplacer celui par défaut. Ce que j'ai fait est comme suit:

_@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);
        }
    }
}
_

Fondamentalement, j’ai écrasé celui par défaut en ajoutant un gestionnaire de ressources de la plus haute valeur en appelant registry.setOrder (Integer.MIN_VALUE).

Étant donné que celui par défaut dans Spring Boot a la valeur de commande (Integer.MIN_VALUE + 1), (voir la classe FaviconConfiguration dans https://github.com/spring-projects/spring-boot/blob/master/spring- boot-autoconfigure/src/main/Java/org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration.Java ) mon gestionnaire gagne.

Est-ce correct? Y a-t-il un autre moyen (quelque chose de plus doux que ce que j'ai fait)?

[~ # ~] met à jour [~ # ~]

Ce n'est pas ok. Lorsque j'appelle registry.setOrder(Integer.MIN_VALUE), je lève en fait la priorité de tous les gestionnaires de ressources. Ainsi, lorsque j'ajoute le code suivant à un autre WebMvcConfigurerAdapter, toutes les requêtes http sont effectivement dirigées vers ce gestionnaire de ressources, ce qui empêche toute manipulation dynamique par Java.

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

Une autre solution est nécessaire.

[~ # ~] met à jour [~ # ~]

Pour l'instant, je n'ai pas trouvé le moyen de remplacer les fonctionnalités de favicon fournies par Spring Boot.
Peut-être qu’il existe un moyen d’ajouter mon propre haricot HandlerMapping, mais je ne sais pas comment le faire.

Maintenant, je peux choisir l'une des options suivantes:

  1. Avoir une classe qui a _@EnableWebMvc_ désactivant ainsi la classe Spring Boot WebMvcAutoConfiguration. (Je peux copier le code de la classe WebMvcAutoConfiguration et supprimer la fonctionnalité favicon)
  2. Abandonnez la liberté de placer le fichier favicon dans un emplacement arbitraire et placez-le dans le répertoire de ressources comme l'exige la fonctionnalité favicon. Et ignorer le problème de mise en cache.

Mais aucune option n'est satisfaisante.
Je souhaite simplement placer le fichier favicon avec mes fichiers Web statiques (qui peuvent être n’importe quel répertoire car je peux changer la racine du document) et résoudre le problème de la mise en cache.
Est-ce que je manque quelque chose?
Toute suggestion serait grandement appréciée.

[~ # ~] met à jour [~ # ~]

BTW, la raison pour laquelle je veux changer l'emplacement de favicon et d'autres fichiers statiques est la suivante. Pour le moment, il s’agit principalement de l’environnement de développement.

Je construis une application Web d'une seule page (SPA).

Bibliothèques/cadres:

  • Pour le côté serveur, j'utilise Spring. (bien sûr)
  • Pour le côté client (navigateur Web), j'utilise AngularJS.

Outils:

  • Pour le côté serveur, j'utilise Spring Tool Suite.
  • Pour le côté client, j'utilise WebStorm.

Structure du répertoire principal:

_ProjectRoot\
    src\
    bin\
    build\
    webapp\
    build.gradle
_
  • src: Where the Spring Java).
  • bin: où Spring Tool Suite place sa sortie de génération.
  • build: Où 'gradle build' place sa sortie de construction.
  • webapp: Où résident mes fichiers source client (.js, .css, .htm et favicon). Il s’agit donc du répertoire du projet WebStorm. (Je peux changer le nom du répertoire si nécessaire)

Ce que je veux c'est:

  • Pour pouvoir modifier et tester mon code client sans reconstruire/redémarrer mon application serveur Spring. Le code client ne doit donc pas être placé dans le fichier jar. Anyway Spring Tool Suite ne construit pas du tout un fichier jar (du moins pour la configuration actuelle)
  • Pour pouvoir tester mon application serveur Spring avec le code client, basculez facilement entre la sortie Spring Tool Suite et la sortie dégradée. Ainsi, le code client doit être accessible à la fois de l'application serveur dans le sous-répertoire build (en réalité, _build\libs_) et de l'application serveur dans le répertoire bin.
  • Lorsque je modifie le code client, il doit être immédiatement disponible pour le navigateur Web. Le navigateur ne doit donc pas le mettre indéfiniment en cache, mais doit toujours demander au serveur de le mettre à jour.
  • Une fois déployé, le code client doit être modifiable sans reconstruire/redémarrer l'application serveur. Donc, le code client ne doit pas être placé dans le fichier jar.

En ce qui concerne le problème de cache:

Sans setCachePeriod (0) sur addResourceHandlers (), Google Chrome met le fichier en cache indéfiniment, sans demander au serveur de mises à jour. Il ne se connecte même pas au serveur. (Les ingénieurs de Google disent que le comportement est Donc, tout ce que je peux faire est d’effacer manuellement le cache du navigateur, c’est frustrant pour l’environnement de développement et inacceptable pour l’environnement de production.

BTW, module express.js sur Node.js donne un en-tête HTTP par défaut raisonnable pour que Google Chrome demande des mises à jour au serveur. Lorsque j’ai examiné les en-têtes HTTP générés par Spring et express.js avec Fiddler, ils étaient différents.

Toute suggestion pour améliorer mon environnement serait appréciée.
Depuis que je suis débutant au printemps, il se peut que je manque quelque chose.

[~ # ~] met à jour [~ # ~]

Enfin, j'ai un code de travail. C'est comme suit:

_@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;
    }
}
_

Notez les noms de haricots. J'ai ajouté 'mon' pour éviter les conflits de noms.
Le contexte d’application de câblage automatique lui-même semble maladroit, mais il était nécessaire de mimer le code dans org.springframework.web.servlet.config.annotation.ResourceHandlerRegistration.addResourceLocations().

Maintenant, j'ai un gestionnaire de favicon exempt de problème de cache, et je peux placer le fichier de favicon n'importe où.
Merci.

75
zeodtr

Vous pouvez simplement mettre votre propre fichier favicon.ico à la racine du chemin de classe ou à n’importe quel emplacement de ressource statique (par exemple, classpath:/static). Vous pouvez également désactiver complètement la résolution des favicon avec un seul drapeau spring.mvc.favicon.enabled=false.

Ou pour prendre le contrôle complet, vous pouvez ajouter un HandlerMapping (copiez simplement celui de Boot et donnez-lui une priorité plus élevée), par exemple.

@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

Rien de tout cela n'était nécessaire pour moi.

Pourquoi remplacer la valeur par défaut lorsque vous pouvez regrouper une ressource avec le fichier JAR généré qui aura une priorité supérieure à celle par défaut.

Pour réaliser une personnalisation favicon.ico fichier, j'ai créé un src/main/resources répertoire pour mon application, puis copié le favicon.ico fichier dans cet endroit. Les fichiers de ce répertoire de ressources sont déplacés vers la racine du fichier JAR compilé et, par conséquent, votre fichier personnalisé favicon.ico se trouve avant le printemps fourni.

Ce qui précède a eu le même effet que votre solution mise à jour ci-dessus.

Notez que depuis la version 1.2.0, vous pouvez également placer le fichier dans src/main/resources/static.

73
Ross

J'aime beaucoup Springboot car, dans l’ensemble, il regorge de solutions intelligentes, mais je refuse d’enregistrer un bean application pour fournir un favicon, car c’est tout simplement stupide.

Je viens d'ajouter mon propre lien de favicon dans la tête de ma page html, comme ça.

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

Ensuite, j'ai renommé mon favicon et l'ai placé à

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

Maintenant, j'ai une icône dans Chrome et les onglets du navigateur Firefox et la barre d'adresse Safari) sans avoir à utiliser Spring et Java, et je ne devrais pas avoir à poursuivre les modifications apportées à Springboot dans des versions plus récentes pour une fonctionnalité aussi triviale. .

26
jeremyjjbrown

Depuis Spring Boot 1.2.2 et 1.1.11, vous pouvez facilement désactiver le favicon par défaut en utilisant spring.mvc.favicon.enabled = false propriété.

Pour plus d'informations visitez:

13
Trynkiewicz Mariusz

Les versions les plus récentes de Boot (1.2 bien sûr mais peut-être aussi 1.1.8) vous permettent simplement de mettre un favicon.ico dans vos ressources statiques.

2
Dave Syer

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

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

robots.txt, emplacement du fichier favicon.ico:/src/main/resources

j'ai utilisé botte à ressort 1.2.1

1
webmadeup