[JAVA] Paramètres du gestionnaire de ressources lors de la livraison du SPA avec la fonction de ressource statique de Spring Boot

La fonction de distribution de ressources statiques de SpringBoot est une fonction très pratique, mais vous ne pouvez pas y accéder sauf pour la page d'accueil, sauf si vous spécifiez le nom du fichier jusqu'à l'extension. Un SPA général a une fonction de routage qui utilise l'API HTML5 History, et bien que plusieurs URL soient attribuées à chaque page, le seul fichier HTML à préparer est index.html. Par conséquent, si SPA est fourni en tant que ressource statique avec les paramètres par défaut de Spring Boot, la page ne peut pas être affichée correctement lors de l'accès direct à une autre page que la page principale ou lorsque l'écran est actualisé.

Ce que vous voulez réaliser

Nous considérerons une méthode de réglage qui répond aux exigences suivantes.

La présence ou l'absence d'une extension permet de déterminer si la cible d'accès est une page ou un fichier. L'accès à une URL sans extension est considéré comme un accès à la page et renvoie index.html.

Solution de contournement 1: utilisez le routage de hachage du côté SPA

Le moyen le plus simple est d'utiliser le mode hachage dans les paramètres du routeur du côté SPA (ce qui suit est un exemple de Nuxt.js).

js:nuxt.config.js


module.exports = {
  mode: 'spa',
  router: {
    mode: 'hash'
  },
  ......

Quel que soit le routage du côté SPA, la requête au serveur sera toujours l'accès à la page d'accueil. Avec les paramètres par défaut de SpringBoot, index.html est renvoyé en tant que réponse en tant que WelcomePage, de sorte que toutes les URL de page sont valides.

Solution de contournement 2: définir le mappage de demande Spring Boot

Si vous ne voulez pas abandonner le mode historique, vous devez le configurer du côté Spring Boot.

À propos de la livraison de ressources statiques avec les paramètres par défaut

Tout d'abord, vérifions comment la distribution des ressources statiques de Spring Boot est définie par défaut.

Le paramètre par défaut est WebMvcAutoConfiguration.java du module spring-boot-autoconfigure. -Il est décrit dans (autoconfigure / src / main / java / org / springframework / boot / autoconfigure / web / servlet / WebMvcAutoConfiguration.java). Dans cette classe, le mappage pour les ressources statiques suivantes est défini.

Si vous définissez le niveau de journalisation de ʻorg.springframework.web` sur DEBUG, vous pouvez confirmer qu'il est défini comme suit dans la sortie du journal au démarrage.

app.log


2018-06-05 23:17:29.654  INFO 18345 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-06-05 23:17:29.655  INFO 18345 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-06-05 23:17:29.732  INFO 18345 --- [           main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
2018-06-05 23:17:29.915 DEBUG 18345 --- [           main] o.s.w.s.resource.ResourceUrlProvider     : Looking for resource handler mappings
2018-06-05 23:17:29.916 DEBUG 18345 --- [           main] o.s.w.s.resource.ResourceUrlProvider     : Found resource handler mapping: URL pattern="/**/favicon.ico", locations=[class path resource [META-INF/resources/], class path resource [resources/], class path resource [static/], class path resource [public/], ServletContext resource [/], class path resource []], resolvers=[org.springframework.web.servlet.resource.PathResourceResolver@3b4ef7]
2018-06-05 23:17:29.916 DEBUG 18345 --- [           main] o.s.w.s.resource.ResourceUrlProvider     : Found resource handler mapping: URL pattern="/webjars/**", locations=[class path resource [META-INF/resources/webjars/]], resolvers=[org.springframework.web.servlet.resource.PathResourceResolver@1af05b03]
2018-06-05 23:17:29.916 DEBUG 18345 --- [           main] o.s.w.s.resource.ResourceUrlProvider     : Found resource handler mapping: URL pattern="/**", locations=[class path resource [META-INF/resources/], class path resource [resources/], class path resource [static/], class path resource [public/], ServletContext resource [/]], resolvers=[org.springframework.web.servlet.resource.PathResourceResolver@5987e932]

Méthode de réglage

Modifier le modèle de mappage de ressources statiques

Ajoutez un paramètre à application.yml pour renvoyer des ressources statiques uniquement pour les chemins avec des extensions. Le modèle de mappage par défaut vers les ressources statiques est défini dans spring.mvc.static-path-pattern et sera remplacé.

application.yml


spring:
  mvc:
    static-path-pattern: /**/*.*

Ajouter un gestionnaire de ressources pour l'URL de la page

Avec les paramètres ci-dessus, l'accès à l'URL de la page s'écartera des paramètres de mappage du gestionnaire de ressources statiques par défaut. Par conséquent, définissez la configuration suivante en référence à WebMvcAutoConfiguration.java afin que index.html soit renvoyé lorsque la ressource cible n'existe pas pour accéder à l'URL de la page.

Html5HistoryModeResourceConfig.java


@Configuration
public class Html5HistoryModeResourceConfig implements WebMvcConfigurer {

    @Autowired
    private ResourceProperties resourceProperties;

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry
            .addResourceHandler("/**")
            .addResourceLocations(resourceProperties.getStaticLocations())
            .resourceChain(false)
            .addResolver(new SpaPageResourceResolver());
    }

    public static class SpaPageResourceResolver extends PathResourceResolver {
        @Override
        protected Resource getResource(String resourcePath, Resource location) throws IOException {
            Resource resource = super.getResource(resourcePath, location);
            return resource != null ? resource : super.getResource("index.html", location);
        }
    }
}

Étant donné que les paramètres par défaut sont prioritaires, les gestionnaires de ressources sont définis pour tous les autres chemins. Le chemin de stockage des ressources statiques est obtenu à partir de l'instance ResourceProperties afin que le paramètre spring.resources.static-locations puisse être utilisé tel quel. Le dernier SpaPageResourceResolver enregistré dans ʻaddResolver` retourne la réponse de index.html du chemin racine.

Si la classe de configuration ci-dessus est chargée au démarrage, elle doit apparaître dans le journal de démarrage comme indiqué ci-dessous.

app.log


2018-06-05 23:42:22.481  INFO 18576 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-06-05 23:42:22.481  INFO 18576 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**/*.*] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-06-05 23:42:22.481  INFO 18576 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-06-05 23:42:22.781 DEBUG 18576 --- [           main] o.s.w.s.resource.ResourceUrlProvider     : Looking for resource handler mappings
2018-06-05 23:42:22.782 DEBUG 18576 --- [           main] o.s.w.s.resource.ResourceUrlProvider     : Found resource handler mapping: URL pattern="/**/favicon.ico", locations=[class path resource [META-INF/resources/], class path resource [resources/], class path resource [static/], class path resource [public/], ServletContext resource [/], class path resource []], resolvers=[org.springframework.web.servlet.resource.PathResourceResolver@1af1347d]
2018-06-05 23:42:22.782 DEBUG 18576 --- [           main] o.s.w.s.resource.ResourceUrlProvider     : Found resource handler mapping: URL pattern="/webjars/**", locations=[class path resource [META-INF/resources/webjars/]], resolvers=[org.springframework.web.servlet.resource.PathResourceResolver@632aa1a3]
2018-06-05 23:42:22.782 DEBUG 18576 --- [           main] o.s.w.s.resource.ResourceUrlProvider     : Found resource handler mapping: URL pattern="/**/*.*", locations=[class path resource [META-INF/resources/], class path resource [resources/], class path resource [static/], class path resource [public/], ServletContext resource [/]], resolvers=[org.springframework.web.servlet.resource.PathResourceResolver@20765ed5]
2018-06-05 23:42:22.782 DEBUG 18576 --- [           main] o.s.w.s.resource.ResourceUrlProvider     : Found resource handler mapping: URL pattern="/**", locations=[class path resource [META-INF/resources/], class path resource [resources/], class path resource [static/], class path resource [public/]], resolvers=[com.test.spa.Html5HistoryModeResourceConfig$SpaPageResourceResolver@3b582111]

Résumé

En ce qui concerne le déploiement de SPA, je pense qu'il existe une autre meilleure méthode pour le fonctionnement à grande échelle et le SSR, mais si vous démarrez le fichier jar seul comme Jenkins, l'écran viendra avec. Si vous voulez le faire, je pense que ce réglage est efficace.

Lien de référence

Spring Boot Reference Guide - 27.1.5 Static Content https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-developing-web-applications.html#boot-features-spring-mvc-static-content

Comprendre l'accès aux ressources statiques sur Spring MVC (+ Spring Boot) -Qiita https://qiita.com/kazuki43zoo/items/e12a72d4ac4de418ee37

Goslings Development Memo-Part 5: Spring Boot Final (Static Resource Processing) | À décider https://www.kaitoy.xyz/2017/01/24/goslings-development-memo5-spring-boot-static-resources /

html5 - Spring Boot with AngularJS html5Mode - Stack Overflow https://stackoverflow.com/questions/24837715/spring-boot-with-angularjs-html5mode

spring - Springboot/Angular2 - How to handle HTML5 urls? - Stack Overflow https://stackoverflow.com/questions/38516667/springboot-angular2-how-to-handle-html5-urls

Recommended Posts

Paramètres du gestionnaire de ressources lors de la livraison du SPA avec la fonction de ressource statique de Spring Boot
Spécifiez le codage des ressources statiques dans Spring Boot
Accédez au h2db intégré de Spring Boot avec jdbcTemplate
À propos de la fonction de Spring Boot en raison de différentes versions
Une histoire remplie des bases de Spring Boot (résolu)
Mémorandum lorsque Spring Boot 1.5.10 → Spring Boot 2.0.0
Voir le comportement des mises à jour d'entités avec Spring Boot + Spring Data JPA
Comment accéder directement à Socket avec la fonction TCP de Spring Integration
Implémenter la fonction de pagination avec Spring Boot + Thymeleaf
Présentation de Spring Boot Actuator, une fonctionnalité qui facilite l'utilisation des applications Spring Boot
Organisez les différences de comportement de @NotBlank, @NotEmpty et @NotNull avec Spring Boot + Thymeleaf
L'histoire de la montée de la série Spring Boot 1.5 à la série 2.1
Vérifions la sensation de Spring Boot + Swagger 2.0
Lorsque @Transactional of Spring Boot ne fonctionne pas
[Introduction à Spring Boot] Fonction d'authentification avec Spring Security
[Spring Boot] L'histoire selon laquelle le bean de la classe avec l'annotation ConfigurationProperties n'a pas été trouvé
Lors du téléchargement d'un fichier avec Spring Boot, la gestion des erreurs est effectuée lorsque la taille maximale du fichier est dépassée.
Paramètres de connexion à MySQL avec Spring Boot + Spring JDBC
[Note] Fichier de configuration lors de l'utilisation de Logback avec Spring Boot
Ressort avec Kotorin ―― 3. Omettre les crochets d'onde de la fonction
J'ai essayé de réduire la capacité de Spring Boot
Spring Boot avec les paramètres du filtre de sécurité Spring et les points addictifs
Créer Restapi avec Spring Boot (jusqu'à l'exécution de l'application)
Une note de révision de l'interface Spring Framework Resource
Comment démarrer par environnement avec Spring Boot de Maven
Contrôlez le flux de traitement Spring Batch avec JavaConfig.
Télécharger avec Spring Boot
Changez la cible d'injection pour chaque environnement avec Spring Boot 2
Découpez SQL en fichier de propriété avec jdbcTemplate of spring boot
Essayez d'utiliser l'API de recherche de code postal avec Spring Boot
Spécifiez le code de caractère de la source lors de la construction avec Maven
Application Spring Boot qui spécifie les paramètres de connexion à la base de données avec des paramètres
Introduction de la bibliothèque ff4j qui réalise le basculement de fonctionnalités avec Spring Boot
Une histoire qui m'a fait regretter quand une "NotReadablePropertyException" s'est produite pendant le développement de l'application Spring Boot.