Notre premier contrôleur
Notions théoriques
Le rôle du contrôleur
Un contrôleur est une classe Java qui répond aux requêtes HTTP. Chaque méthode d'un contrôleur correspond à une URL (une route) et retourne une réponse (une vue HTML ou des données JSON).
| Symfony (PHP) | Spring Boot (Java) |
|---|---|
#[Route('/')] | @GetMapping("/") |
public function index(): Response | public String index(Model model) |
return $this->render('accueil.html.twig', [...]) | return "accueil"; |
Classe avec #[AsController] ou dans Controller/ | Classe avec @Controller |
@Controller vs @RestController
Spring Boot propose deux types de contrôleurs :
@Controller — retourne des vues HTML (pages web). La méthode retourne le nom d'un template Thymeleaf (une chaîne de caractères). C'est ce que nous utilisons dans ce cours.
@Controller
public class AccueilController {
@GetMapping("/")
public String index() {
return "accueil"; // → cherche templates/accueil.html
}
}
@RestController — retourne des données JSON (API REST). La méthode retourne directement un objet Java, converti automatiquement en JSON par Jackson.
@RestController
public class ArticleApiController {
@GetMapping("/api/articles")
public List<String> listeArticles() {
return List.of("Article 1", "Article 2");
// → {"articles": ["Article 1", "Article 2"]}
}
}
Dans ce cours, utilisez toujours @Controller (pas @RestController) sauf pour la séance dédiée à l'API REST (séance 540).
Le Model pour passer des données à la vue
Pour transmettre des données du contrôleur à la vue Thymeleaf, on utilise un objet Model :
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class AccueilController {
@GetMapping("/")
public String index(Model model) {
// Ajouter un attribut accessible dans la vue
model.addAttribute("titre", "Bienvenue sur MonBlog");
model.addAttribute("nombreArticles", 42);
// Retourne le nom du template (sans l'extension .html)
return "accueil";
}
}
Dans la vue Thymeleaf, on accède aux attributs avec ${nomAttribut} — exactement comme {{ variable }} dans Twig.
Les annotations de mapping
| Annotation | Méthode HTTP | Utilisation typique |
|---|---|---|
@GetMapping("/url") | GET | Afficher une page |
@PostMapping("/url") | POST | Traiter un formulaire |
@PutMapping("/url") | PUT | Mettre à jour (API REST) |
@DeleteMapping("/url") | DELETE | Supprimer (API REST) |
@RequestMapping("/url") | Toutes | Mapper la classe entière |
Créer la vue Thymeleaf
Les templates Thymeleaf sont des fichiers HTML placés dans src/main/resources/templates/.
<!DOCTYPE html>
<html lang="fr" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>MonBlog</title>
</head>
<body>
<h1 th:text="${titre}">Titre par défaut</h1>
<p>Il y a <span th:text="${nombreArticles}">0</span> articles.</p>
</body>
</html>
L'attribut xmlns:th="http://www.thymeleaf.org" est indispensable dans la balise <html> pour activer les attributs th:*. Sans lui, IntelliJ signale des erreurs.
Variables de chemin avec @PathVariable
@GetMapping("/articles/{id}")
public String detail(@PathVariable Long id, Model model) {
model.addAttribute("articleId", id);
return "articles/detail";
}
Exemple pratique
Voici un contrôleur complet pour la page d'accueil du blog, avec transmission de données à la vue :
package org.joliciel.monblog.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@Controller
public class AccueilController {
// Route : GET /
@GetMapping("/")
public String index(Model model) {
model.addAttribute("titre", "Bienvenue sur MonBlog");
model.addAttribute("description", "Le blog des passionnés de Java");
return "accueil"; // → templates/accueil.html
}
// Route : GET /articles/{id}
@GetMapping("/articles/{id}")
public String detail(@PathVariable Long id, Model model) {
model.addAttribute("articleId", id);
model.addAttribute("articleTitre", "Article numéro " + id);
return "articles/detail"; // → templates/articles/detail.html
}
}
Et le template correspondant templates/accueil.html :
<!DOCTYPE html>
<html lang="fr" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title th:text="${titre}">MonBlog</title>
</head>
<body>
<h1 th:text="${titre}">Titre</h1>
<p th:text="${description}">Description du blog.</p>
<a th:href="@{/articles/1}">Voir l'article 1</a>
</body>
</html>
Test de mémorisation/compréhension
TP pour réfléchir et résoudre des problèmes
Dans ce TP, vous allez créer le premier contrôleur de MonBlog et la page d'accueil correspondante.
Étape 1 — Créer le package controller
Dans IntelliJ, créez un nouveau package controller sous org.joliciel.monblog, puis créez la classe AccueilController.
Placez tous vos contrôleurs dans un sous-package controller (ex: org.joliciel.monblog.controller). Cela rend la structure du projet lisible : tous les contrôleurs au même endroit, comme le dossier src/Controller/ en Symfony.
Étape 2 — Ajouter la méthode index
Essayez d'avoir une correspondance claire entre l'URL et le nom du template. La route /articles retourne le template "articles/liste", la route /articles/{id} retourne "articles/detail". Cela facilite la navigation dans le projet.
Étape 3 — Créer le template Thymeleaf
Créez le fichier src/main/resources/templates/accueil.html et utilisez th:text pour afficher le titre.
Le texte entre les balises HTML (Titre par défaut) est remplacé par Thymeleaf à l'exécution. Mais il s'affiche si vous ouvrez le fichier HTML directement dans un navigateur (sans serveur). C'est utile pour prévisualiser la mise en page pendant le développement.