Contactez-nous

Spring Boot et les serveurs embarqués (Tomcat, Jetty, Undertow)

Découvrez comment Spring Boot intègre des serveurs web comme Tomcat, Jetty et Undertow pour créer des applications autonomes et simplifier le déploiement.

La révolution des serveurs embarqués

L'une des caractéristiques les plus appréciées et révolutionnaires de Spring Boot est son support intégré pour les serveurs web embarqués. Avant Spring Boot, le déploiement typique d'une application web Java impliquait de packager l'application sous forme d'un fichier WAR (Web Application Archive) et de le déployer ensuite sur un serveur d'applications ou un conteneur de servlets externe (comme une instance de Tomcat, JBoss/WildFly ou WebSphere installée et gérée séparément).

Spring Boot inverse cette approche. Au lieu de déployer votre application sur un serveur, le serveur est intégré (embarqué) directement dans votre application. Lorsque vous construisez votre projet Spring Boot (par exemple, avec `spring-boot-starter-web`), le serveur (Tomcat par défaut) est inclus comme une simple dépendance JAR. Votre application devient alors une archive JAR auto-exécutable (souvent appelée "fat JAR" ou "uber JAR") qui contient tout le nécessaire pour fonctionner : votre code, les dépendances Spring, et le serveur lui-même.

Cela simplifie énormément le processus de développement, de test et de déploiement. Il suffit de lancer le JAR (via java -jar mon-app.jar) et votre application web démarre, prête à servir des requêtes, sans aucune configuration de serveur externe requise.

Tomcat : Le choix par défaut

Par défaut, lorsque vous incluez le starter spring-boot-starter-web dans votre projet Maven ou Gradle, Spring Boot inclut et configure automatiquement Apache Tomcat comme serveur embarqué.



    org.springframework.boot
    spring-boot-starter-web



// build.gradle (Gradle)
implementation 'org.springframework.boot:spring-boot-starter-web'

// Ce starter apporte transitivement spring-boot-starter-tomcat

Tomcat est le conteneur de servlets le plus largement utilisé dans l'écosystème Java, connu pour sa maturité, sa stabilité et sa large communauté. Spring Boot gère le démarrage et l'arrêt du serveur Tomcat intégré lorsque vous lancez et arrêtez votre application.

Alternatives : Jetty et Undertow

Bien que Tomcat soit le défaut, Spring Boot supporte également deux autres excellents serveurs embarqués : Jetty et Undertow.

  • Jetty : Un projet open-source mature de la fondation Eclipse, connu pour sa légèreté, sa faible empreinte mémoire et ses bonnes performances, particulièrement dans les scénarios avec un grand nombre de connexions de courte durée.
  • Undertow : Un serveur web moderne développé par JBoss (Red Hat), connu pour sa haute performance, sa flexibilité et son support des dernières technologies web comme HTTP/2 et les WebSockets. Il est souvent considéré comme plus performant et moins gourmand en ressources que Tomcat dans de nombreux benchmarks.

Pour utiliser Jetty ou Undertow à la place de Tomcat, vous devez :

  1. Exclure la dépendance spring-boot-starter-tomcat du starter web.
  2. Ajouter la dépendance du starter pour le serveur souhaité (spring-boot-starter-jetty ou spring-boot-starter-undertow).

Exemple pour utiliser Jetty (Maven) :


    org.springframework.boot
    spring-boot-starter-web
    
        
            org.springframework.boot
            spring-boot-starter-tomcat
        
    


    org.springframework.boot
    spring-boot-starter-jetty

Exemple pour utiliser Undertow (Gradle) :

implementation('org.springframework.boot:spring-boot-starter-web') {
    exclude group: 'org.springframework.boot', module: 'spring-boot-starter-tomcat'
}
implementation 'org.springframework.boot:spring-boot-starter-undertow'

Une fois ces modifications faites dans votre fichier de build, Spring Boot détectera automatiquement le nouveau starter et configurera Jetty ou Undertow comme serveur embarqué au prochain démarrage.

Configuration du serveur embarqué

Spring Boot permet de configurer facilement les propriétés courantes du serveur embarqué via le fichier application.properties ou application.yml. Ces propriétés sont généralement préfixées par server.*.

Voici quelques exemples courants :

# application.properties

# Port d'écoute du serveur (défaut 8080)
server.port=8090

# Chemin de contexte de l'application (défaut /)
server.servlet.context-path=/myapp

# Adresse IP sur laquelle écouter (défaut : toutes les interfaces)
# server.address=192.168.1.100

# Activation de la compression HTTP (gzip)
server.compression.enabled=true
server.compression.mime-types=application/json,text/css,application/javascript # Types MIME à compresser
server.compression.min-response-size=2048 # Taille minimale pour compresser (octets)

# Configuration SSL/TLS (HTTPS)
# server.ssl.enabled=true
# server.ssl.key-store=classpath:keystore.p12
# server.ssl.key-store-password=secret
# server.ssl.key-store-type=PKCS12
# server.ssl.key-alias=tomcat
# application.yml
server:
  port: 8090
  servlet:
    context-path: /myapp
  # address: 192.168.1.100 
  compression:
    enabled: true
    mime-types:
      - application/json
      - text/css
      - application/javascript
    min-response-size: 2048
#  ssl:
#    enabled: true
#    key-store: classpath:keystore.p12
#    key-store-password: secret
#    key-store-type: PKCS12
#    key-alias: tomcat

De nombreuses autres options spécifiques à Tomcat, Jetty ou Undertow sont disponibles sous les préfixes server.tomcat.*, server.jetty.* et server.undertow.* respectivement (par exemple, pour configurer le nombre de threads, les timeouts, etc.).

Personnalisation avancée avec `WebServerFactoryCustomizer`

Pour des besoins de configuration plus avancés qui ne sont pas couverts par les propriétés standard, Spring Boot offre l'interface WebServerFactoryCustomizer. En implémentant cette interface et en déclarant votre classe comme un bean Spring (@Component), vous pouvez accéder programmatiquement à la fabrique du serveur web (par exemple, TomcatServletWebServerFactory) avant sa création et appliquer des configurations spécifiques.

import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
import org.springframework.stereotype.Component;

@Component
public class CustomWebServerFactoryCustomizer 
       implements WebServerFactoryCustomizer {

    @Override
    public void customize(ConfigurableServletWebServerFactory factory) {
        // Exemple : Définir le port programmatiquement (même si les propriétés sont préférées pour cela)
        // factory.setPort(9000);
        
        // Exemple : Ajouter un connecteur HTTP supplémentaire si HTTPS est activé
        // if (factory instanceof TomcatServletWebServerFactory) {
        //     TomcatServletWebServerFactory tomcatFactory = (TomcatServletWebServerFactory) factory;
        //     tomcatFactory.addAdditionalTomcatConnectors(createHttpConnector());
        // }
        
        System.out.println("Personnalisation de la fabrique du serveur web appliquée !");
    }
    
    /*
    private Connector createHttpConnector() {
        Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
        connector.setScheme("http");
        connector.setPort(8080); // Port HTTP
        connector.setSecure(false);
        connector.setRedirectPort(8443); // Port HTTPS vers lequel rediriger si nécessaire
        return connector;
    }
    */
}

Cette approche offre une flexibilité maximale pour des configurations très spécifiques au serveur choisi (ajout de Valves Tomcat, configuration de handlers Jetty, etc.).

En conclusion, le support des serveurs embarqués est une pierre angulaire de la philosophie de Spring Boot, simplifiant radicalement le développement et le déploiement d'applications web Java modernes et autonomes.