Spring Boot / Angular – Comment gérer les URL HTML 5 ?

Dans le cas d’une utilisation sans le hash dans les chemins Angular, vous allez être confronté à un problème de compréhension des URL par les contrôleurs de Spring Boot et celui-ci risque de vous répondre avec la page d’erreur standard :

Whitelabel Error Page
There was an unexpected error (type=Not Found, status=404).
No message available

Spring ne doit donc répondre qu’aux demandes dédiées aux API REST. Pour cela, il suffit de mettre en place un contrôleur (et non un contrôleur REST) retournant les demandes à Angular.

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
 
@Controller
public class AngularRedirectionController {
 
    // Redirection pour que le HTML 5 mode fonctionne (par opposition au hashtag routing).
    @RequestMapping(value = {"{path:(?:(?!api|\.).)*}/**"})
    public String redirect() {
        return "forward:/";
    }
}

Le prefixe forward utilisé ici retourne exactement la même requête à l’URL cible, ne changeant pas l’historique des URL du navigateur, ce qui évite un refresh de la page.

Autre élément important, l’expression régulière utilisée pour filtrer les appels. RequestMapping utilise la notion de PathMatcher. Sur le blog de Spring, il est recommandé d’utiliser l’expression suivante : /{[path:[^\\.]*}. Cependant, cette expression n’est pas complètement juste (les commentaires en bas de leur page ne font que confirmer mon affirmation), car elle n’exclura pas les appels vers vos API et encore moins les routes ayant plusieurs niveaux.

L’expression fournit par Spring permet de filtrer tous les chemins qui ne contiennent pas de point (et qui ne sont pas explicitement mappés) et sont donc obligatoirement des chemins Angular. J’ai rajouté deux notions:

  • L’exclusion des chemins relatifs contenant le mapping utilisé par nos API Spring Boot: (?!api|\.)
  • La prise en charge des routes imbriquées: /**

On peut également faire référence à une valeur de notre fichier application.yml afin de paramétrer la route de nos API. Si vous utilisez Spring Data REST, cela se modélisera de la manière suivante:

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
 
@Controller
public class AngularRedirectionController {
 
    // Redirection pour que le HTML 5 mode fonctionne (par opposition au hashtag routing).
    @RequestMapping(value = {"{path:(?:(?!systemProperties:[spring.data.rest.base-path]|\.).)*}/**"})
    public String redirect() {
        return "forward:/";
    }
}

Ce qui correspond dans le fichier application.yml à :

spring: 
  data:
    rest:
      base-path: /api/data

Ressources

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.