Botte de spring: favicon

Comment puis-je remplacer le favicon de Spring Boot?

NOTE : Voici une autre question qui fournit une autre solution qui n’implique pas de codage: Spring Boot: Est-il possible d’utiliser des fichiers externes application.properties dans des répertoires arbitraires avec un fat jar? C’est pour application.properties, mais il peut également être appliqué au favicon. En fait, j’utilise cette méthode pour contourner les favicon maintenant.

Si j’implémente une classe avec @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 il sert l’icône “feuille verte” qui est placée dans le répertoire de ressources principal de Spring Boot.

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

De plus, comme je souhaite que le fichier icône soit mis à jour le plus rapidement 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 contenu webapp “statique” et fichiers de script qui doivent être mis à jour du côté client dès que possible après avoir modifié le fichier.)

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

Donc, juste pour trouver l’endroit où enregistrer le fichier favicon.ico que les honneurs faviconRequestHandler de Spring Boot peuvent ne pas être suffisants.

METTRE À 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 persiste.
En outre, il est préférable de placer le fichier favicon dans le répertoire où sont placés les fichiers Web statiques, plutôt que dans le répertoire des ressources.

METTRE À JOUR

Ok, j’ai réussi à écraser 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); } } } 

En gros, j’ai remplacé l’option par défaut en ajoutant un gestionnaire de ressources avec le plus grand nombre en appelant registry.setOrder (Integer.MIN_VALUE).

Comme la valeur par défaut dans Spring Boot a la valeur d’ordre (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)?

METTRE À JOUR

Ce n’est pas ok. Lorsque j’appelle registry.setOrder(Integer.MIN_VALUE) , je soulève en fait la priorité de tous les gestionnaires de ressources. Ainsi, lorsque j’ajoute du code suivant à un autre WebMvcConfigurerAdapter , toute requête HTTP est dirigée vers ce gestionnaire de ressources, empêchant toute manipulation dynamic par le code Java.

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

Une autre solution est nécessaire.

METTRE À JOUR

Pour l’instant, je n’ai pas pu trouver le moyen de remplacer la fonctionnalité de favicon fournie par Spring Boot.
Peut-être y a-t-il un moyen d’append mon propre bean 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 un fichier favicon à un emplacement arbitraire et placez-le dans le répertoire de ressources comme le requirejs la fonctionnalité favicon de Spring Boot. Et ignorez le problème de mise en cache.

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

METTRE À JOUR

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

Je construis une application web à page unique (SPA).

Bibliothèques / Cadres:

  • Côté serveur, j’utilise Spring. (bien sûr)
  • Côté client (navigateur Web), j’utilise AngularJS.

Outils:

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

Structure de répertoire principale:

 ProjectRoot\ src\ bin\ build\ webapp\ build.gradle 
  • src: Où se trouvent mes fichiers source Java de spring.
  • bin: Où Spring Tool Suite place sa sortie de génération.
  • build: Où ‘gradle build’ place sa sortie de build.
  • webapp: Où résident mes fichiers source client (.js, .css, .htm et favicon). C’est donc le 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. Anyways Spring Tool Suite ne crée aucun fichier jar (du moins pour la configuration actuelle)
  • Pour pouvoir tester mon application serveur Spring avec le code client, basculez facilement entre la sortie de la Spring Tool Suite et la sortie graduelle. Ainsi, le code client doit être accessible à la fois à partir de l’application serveur dans le sous-répertoire build (en fait 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 en cache indéfiniment et doit toujours demander au serveur de le mettre à jour.
  • Lorsqu’il est déployé, le code client doit être modifiable sans reconstruction / redémarrage de l’application serveur. Le code client ne doit donc 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 mémoire cache indéfiniment, sans demander de mises à jour au serveur. Il ne se connecte même pas au serveur. (Les ingénieurs de Google disent que le comportement est correct.) Tout ce que je peux faire, c’est effacer manuellement le cache du navigateur. Il est frustrant pour l’environnement de développement et inacceptable pour l’environnement de production.

BTW, le 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 produits par Spring et express.js avec Fiddler, ils étaient différents.

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

METTRE À 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 . asList(applicationContext.getResource("/"))); requestHandler.setCacheSeconds(0); return requestHandler; } } 

Notez les noms des haricots. J’ai ajouté «my» pour éviter les conflits de noms.
Le contexte de l’application de démarrage automatique lui-même semble difficile, mais il était nécessaire pour imiter le code dans org.springframework.web.servlet.config.annotation.ResourceHandlerRegistration.addResourceLocations() .

Maintenant, j’ai un gestionnaire de favicon exempt de problèmes de mise en cache, et je peux placer le fichier favicon où je veux.
Merci.

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

Ou pour prendre le contrôle complet, vous pouvez append 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 . asList(new ClassPathResource("/"))); return requestHandler; } } 

Rien de 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 la priorité supérieure à celle par défaut.

Pour créer un fichier favicon.ico personnalisé, j’ai créé un répertoire src/main/resources pour mon application, puis copié le fichier favicon.ico . Les fichiers de ce répertoire de ressources sont déplacés à la racine du favicon.ico JAR compilé. Par conséquent, votre favicon.ico personnalisé est trouvé avant que Spring ne le fournisse.

Faire 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 .

J’aime beaucoup Springboot parce que, globalement, il y a plein de solutions intelligentes, mais je refuse d’enregistrer un bean d’application pour fournir un favicon car c’est tout simplement stupide.

Je viens d’append mon propre lien favicon dans ma tête de page HTML comme ça.

  

Puis j’ai renommé mon favicon et l’ai placé à

 /src/main/resources/static/images/fav.png 

J’ai maintenant une icône dans les tabs du navigateur Chrome et Firefox et la barre d’adresses Safari sans avoir à utiliser Spring et Java, et je ne devrais pas avoir à poursuivre les modifications de Springboot dans les nouvelles versions pour une fonctionnalité aussi sortingviale.

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

Pour plus d’informations visitez:

Les nouvelles versions de Boot (à coup sûr 1.2 mais peut-être aussi 1.1.8) vous permettent de simplement placer un favicon.ico dans vos ressources statiques.

registry.addResourceHandler (“/ robots.txt”). addResourceLocations (“/”);

registry.addResourceHandler (“/ favicon.ico”). addResourceLocations (“/”);

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

j’ai utilisé la botte de spring 1.2.1