spring-mvc favicon spring-boot

spring-mvc - favicon generator



Spring Boot: anulaciĆ³n del favicon (6)

¿Cómo puedo anular el favicon de Spring Boot?

NOTA : Aquí está mi otra pregunta que proporciona otra solución que no implica ninguna codificación: Spring Boot: ¿Es posible usar archivos externos de application.properties en directorios arbitrarios con un frasco de grasa? Es para application.properties, pero también se puede aplicar al favicon. De hecho, estoy usando ese método para reemplazar el favicon ahora.

Si implemento una clase que tiene @EnableWebMvc, la clase WebMvcAutoConfiguration de Spring Boot no se carga y puedo servir mi propio favicon colocándolo en el directorio raíz de los contenidos estáticos.

De lo contrario, WebMvcAutoConfiguration registra faviconRequestHandler bean, (ver fuente https://github.com/spring-projects/spring-boot/blob/master/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration.java ) y sirve el icono ''hoja verde'' que se coloca en el directorio principal de recursos del Spring Boot.

¿Cómo puedo anularlo sin implementar una clase que tenga @EnableWebMvc, deshabilitando así toda la funcionalidad de configuración predeterminada de la clase WebMvcAutoConfiguration de Spring Boot?

Además, dado que deseo que el archivo de icono se actualice lo más pronto posible en el lado del cliente (navegador web), quiero establecer el período de caché del archivo de favicon en 0. (como el siguiente código, que estoy usando para mi archivos de script y contenido de aplicación webapp ''estáticos'' que deben actualizarse en el lado del cliente lo antes posible después de que cambie el archivo).

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

Entonces, solo para encontrar el lugar donde guardar el archivo favicon.ico que los honores de faviconRequestHandler de Spring Boot pueden no ser suficientes.

ACTUALIZAR

Ahora sé que puedo anular el predeterminado colocando un archivo de favicon en el directorio src / main / resources. Pero el problema del período de caché aún permanece.
Además, es preferible colocar el archivo de favicon en el directorio donde se colocan los archivos web estáticos, en lugar del directorio de recursos.

ACTUALIZAR

Ok, logré anular el predeterminado. Lo que hice fue lo siguiente:

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

Básicamente, sobreescribo el predeterminado al agregar un manejador de recursos con el orden más alto al llamar a registry.setOrder (Integer.MIN_VALUE).

Dado que el predeterminado en Spring Boot tiene el valor de orden (Integer.MIN_VALUE + 1), (consulte la clase FaviconConfiguration en https://github.com/spring-projects/spring-boot/blob/master/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration.java ) mi manejador gana.

¿Esta bien? ¿Hay alguna otra forma (algo más amable que lo que hice)?

ACTUALIZAR

No está bien. Cuando llamo a registry.setOrder(Integer.MIN_VALUE) , de hecho elevo la prioridad de todos los manejadores de recursos. Entonces, cuando agrego el siguiente código a otro WebMvcConfigurerAdapter , efectivamente toda la solicitud http se dirige a ese manejador de recursos, evitando cualquier manejo dinámico por código Java.

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

Otra solución es necesaria.

ACTUALIZAR

Por ahora, no pude encontrar la manera de anular la funcionalidad de favicon que proporciona Spring Boot.
Tal vez haya una manera de agregar agregar mi propio bean HandlerMapping , pero no sé cómo hacerlo.

Ahora puedo elegir una de las siguientes opciones:

  1. Tenga una clase que tenga @EnableWebMvc y deshabilite la clase Spring Boot WebMvcAutoConfiguration . (Puedo copiar el código de la clase WebMvcAutoConfiguration y eliminar la funcionalidad de favicon)
  2. Renunciar a la libertad de colocar el archivo de favicon en una ubicación arbitraria y colocarlo en el directorio de recursos como lo requiere la funcionalidad de favicon de Spring Boot. E ignore el problema del almacenamiento en caché.

Pero ninguna de las opciones es satisfactoria.
Solo quiero colocar el archivo de favicon con mis archivos web estáticos (que pueden ser cualquier directorio, ya que puedo cambiar la raíz del documento) y resolver el problema del almacenamiento en caché.
¿Me estoy perdiendo de algo?
Cualquier sugerencia sería muy apreciada.

ACTUALIZAR

Por cierto, el motivo por el que quiero cambiar la ubicación de favicon y otros archivos estáticos es el siguiente. Por ahora, es principalmente el problema del entorno de desarrollo.

Estoy construyendo una aplicación web de una sola página (SPA).

Bibliotecas / Frameworks:

  • Por el lado del servidor, uso Spring. (por supuesto)
  • Para el lado del cliente (navegador web), uso AngularJS.

Herramientas:

  • Para el lado del servidor, utilizo Spring Tool Suite.
  • Por el lado del cliente, uso WebStorm.

Estructura de directorio principal:

ProjectRoot/ src/ bin/ build/ webapp/ build.gradle

  • src: Donde residen mis archivos fuente Spring java.
  • bin: Donde Spring Tool Suite coloca su salida de compilación.
  • compilación: donde ''gradle build'' coloca su salida de compilación.
  • webapp: Donde residen los archivos fuente de mi cliente (.js, .css, .htm y favicon). Por lo tanto, este es el directorio del proyecto WebStorm. (Puedo cambiar el nombre del directorio si es necesario)

Lo que quiero es:

  • Para poder modificar y probar mi código de cliente sin reconstruir / reiniciar mi aplicación Spring server. Por lo tanto, el código del cliente no debe colocarse en el archivo jar. De todos modos, Spring Tool Suite no crea un archivo jar en absoluto (al menos para la configuración actual)
  • Para poder probar mi aplicación Spring server con el código del cliente, cambiando fácilmente entre la salida de Spring Tool Suite y la salida de gradle. Por lo tanto, se debe poder acceder al código del cliente tanto desde la aplicación del servidor en el subdirectorio de build (en realidad build/libs ) como desde la aplicación del servidor en el directorio bin .
  • Cuando modifico el código del cliente, debe estar inmediatamente disponible para el navegador web. Por lo tanto, el navegador no debe almacenar en caché de forma indefinida, y siempre debe solicitar la actualización del servidor.
  • Cuando se implementa, el código del cliente debe ser modificable sin reconstruir / reiniciar la aplicación del servidor. Por lo tanto, el código del cliente no debe colocarse en el archivo jar.

En cuanto al problema de caché:

Sin setCachePeriod (0) en addResourceHandlers (), Google Chrome almacena en caché el archivo indefinidamente, sin pedirle actualizaciones al servidor. Ni siquiera se conecta al servidor. (Los ingenieros de Google dicen que el comportamiento es correcto.) Por lo tanto, todo lo que puedo hacer es borrar manualmente el caché del navegador. Es frustrante en el entorno de desarrollo e inaceptable en el entorno de producción.

Por cierto, el módulo express.js en Node.js da un encabezado HTTP predeterminado razonable para que Google Chrome solicite actualizaciones al servidor. Cuando revisé los encabezados HTTP que Spring y express.js producen usando Fiddler, eran diferentes.

Cualquier sugerencia para mejorar mi entorno sería apreciada.
Como soy un principiante de primavera, me puede estar perdiendo algo.

ACTUALIZAR

Finalmente tengo un código de trabajo. Es como sigue:

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

Observe los nombres de los frijoles. He agregado ''mi'' para evitar el choque de nombres.
El contexto de la aplicación de autocableado parece incómodo, pero fue necesario para imitar el código en org.springframework.web.servlet.config.annotation.ResourceHandlerRegistration.addResourceLocations() .

Ahora tengo un manejador de favicon libre de problemas de almacenamiento en caché, y puedo colocar el archivo de favicon en cualquier lugar que desee.
Gracias.



Las versiones más recientes de Boot (1.2 por seguro pero quizás también 1.1.8) le permiten simplemente poner un favicon.ico en sus recursos estáticos.


Nada de esto fue necesario para mí.

¿Por qué anular el valor predeterminado cuando puede agrupar un recurso con el JAR generado que tendrá mayor prioridad que el predeterminado?

Para lograr un archivo favicon.ico personalizado, creé un directorio src/main/resources para mi aplicación y luego copié el archivo favicon.ico allí. Los archivos en este directorio de recursos se mueven a la raíz del JAR compilado y, por lo tanto, su favicon.ico personalizado se encuentra antes que el proporcionado por Spring.

Hacer lo anterior logró el mismo efecto que su solución actualizada anterior.

Tenga en cuenta que desde v1.2.0 también puede colocar el archivo en src/main/resources/static .


Puede simplemente poner su propio favicon.ico en la raíz de la ruta de clase o en cualquiera de las ubicaciones de recursos estáticos (por ejemplo, classpath:/static ). También puede desactivar completamente la resolución de favicon con un solo indicador spring.mvc.favicon.enabled=false .

O para tomar el control completo, puede agregar un HandlerMapping (solo copie el de Boot y asígnele una prioridad más alta), por ej.

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


Realmente me gusta Springboot porque en general está lleno de soluciones inteligentes, pero me niego a registrar un bean de aplicación para proporcionar un favicon porque es simplemente estúpido.

Acabo de agregar mi propio enlace de favicon en mi página html como tal.

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

Luego cambié el nombre de mi favicon y lo coloqué en

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

Ahora tengo un ícono en las pestañas del navegador Chrome y Firefox y la barra de direcciones de Safari sin tener que usar Spring y Java, y no debería tener que buscar cambios en Springboot en versiones más nuevas para una funcionalidad tan trivial.


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

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

robots.txt, ubicación del archivo favicon.ico: / src / main / resources

utilicé el arranque de primavera 1.2.1