Contactez-nous

Utilisation de `@Controller` (différence avec `@RestController`)

Apprenez le rôle de @Controller dans Spring MVC pour le développement web traditionnel et distinguez-le clairement de @RestController utilisé pour les API REST.

Le rôle de `@Controller` dans l'architecture MVC

L'annotation @Controller est l'un des stéréotypes fondamentaux de Spring MVC. Elle est utilisée pour marquer une classe Java comme étant un contrôleur web dans le cadre du pattern Modèle-Vue-Contrôleur. Son rôle principal est de recevoir les requêtes HTTP entrantes, d'invoquer la logique métier appropriée (souvent en déléguant à des beans @Service), de préparer les données nécessaires pour la vue (le modèle) et, enfin, de retourner l'identifiant logique de la vue qui doit être rendue à l'utilisateur.

Les classes annotées avec @Controller sont détectées par le mécanisme de scan des composants de Spring (via @ComponentScan, inclus dans @SpringBootApplication) et sont enregistrées comme des beans gérés par le conteneur Spring. Les méthodes publiques à l'intérieur de ces classes, souvent annotées avec des annotations de mapping comme @RequestMapping, @GetMapping, @PostMapping, etc., deviennent les gestionnaires (handlers) pour des requêtes spécifiques.

Dans une application web MVC traditionnelle, une méthode de handler dans un @Controller ne retourne généralement pas les données brutes directement dans la réponse HTTP. Au lieu de cela, elle retourne typiquement :

  • Un String représentant le nom logique de la vue (par exemple, "userProfile", "productList"). Spring MVC utilise ensuite un ViewResolver (comme celui configuré pour Thymeleaf ou JSP) pour mapper ce nom logique à la ressource de vue réelle (par exemple, /templates/userProfile.html).
  • Un objet ModelAndView qui encapsule à la fois le nom logique de la vue et les données du modèle à lui transmettre.
  • Parfois void, si la méthode gère elle-même l'écriture dans la réponse (moins courant) ou si une redirection est effectuée.

Contraste avec `@RestController` pour les API REST

L'annotation @RestController, introduite dans Spring 4.0, est une annotation de convenance qui combine deux autres annotations : @Controller et @ResponseBody.

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller // Elle EST un Controller
@ResponseBody // MAIS chaque méthode de handler hérite de @ResponseBody
public @interface RestController {
    @AliasFor(annotation = Controller.class)
    String value() default "";
}

@RestController est spécifiquement conçue pour la création d'API RESTful. La présence implicite de @ResponseBody sur chaque méthode de handler change fondamentalement la manière dont la valeur de retour est traitée.

Au lieu d'interpréter la valeur de retour comme un nom de vue, Spring MVC, grâce à @ResponseBody, va :

  1. Prendre l'objet Java retourné par la méthode (par exemple, un DTO, une liste d'objets, une simple chaîne).
  2. Utiliser les convertisseurs de messages HTTP configurés (comme Jackson pour JSON, JAXB pour XML) pour sérialiser cet objet dans un format approprié (généralement JSON).
  3. Ecrire le résultat de cette sérialisation directement dans le corps de la réponse HTTP.

Ainsi, un @RestController est idéal lorsque vous voulez exposer des données ou des services à des clients qui ne sont pas nécessairement des navigateurs web traditionnels (applications JavaScript frontend, applications mobiles, autres microservices), et qui attendent des données structurées (JSON, XML) plutôt qu'une page HTML complète.

La différence fondamentale : Le traitement de la valeur de retour

La distinction essentielle entre @Controller et @RestController réside donc dans le traitement de la valeur retournée par les méthodes de handler :

  • @Controller : Par défaut, la valeur de retour est interprétée comme un identifiant de vue à résoudre par un ViewResolver pour le rendu côté serveur (génération HTML).
  • @RestController : La valeur de retour est sérialisée et écrite directement dans le corps de la réponse HTTP (génération de données type JSON/XML).

Exemple avec `@Controller` (Web traditionnel) :

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 // Pour le rendu de vues HTML
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping("/users/{id}")
    public String getUserProfile(@PathVariable Long id, Model model) {
        User user = userService.findById(id);
        model.addAttribute("user", user); // Ajoute l'utilisateur au modèle pour la vue
        return "userProfile"; // Retourne le nom logique de la vue (ex: userProfile.html)
    }
}

Exemple avec `@RestController` (API REST) :

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

@RestController // Pour retourner des données (JSON/XML)
public class UserApiController {

    @Autowired
    private UserService userService;

    @GetMapping("/api/users/{id}")
    public User getUserData(@PathVariable Long id) {
        User user = userService.findById(id);
        return user; // Retourne l'objet User directement, sera sérialisé en JSON
    }
}

Il est important de noter qu'une classe @Controller peut tout de même avoir certaines méthodes qui retournent des données directement dans le corps de la réponse, à condition d'annoter explicitement ces méthodes spécifiques avec @ResponseBody. Cependant, si la majorité ou la totalité des méthodes d'un contrôleur sont destinées à retourner des données pour une API, il est bien plus pratique et clair d'utiliser directement @RestController.

Quand utiliser `@Controller` ?

Utilisez @Controller lorsque vous construisez une application web où la logique de présentation (le rendu HTML) est principalement effectuée côté serveur. C'est le choix standard pour les applications utilisant des moteurs de templates comme Thymeleaf, FreeMarker, JSP, etc., pour générer dynamiquement les pages web envoyées au navigateur.

Choisissez @Controller si les méthodes de votre classe doivent retourner des noms de vues logiques ou des objets ModelAndView afin que Spring MVC puisse les résoudre et rendre la vue appropriée.

En résumé, la distinction entre @Controller et @RestController est cruciale pour indiquer clairement l'intention de votre contrôleur : servir des vues HTML pour une application web traditionnelle ou servir des données pour une API RESTful.