Jetty est un serveur HTTP et un conteneur de servlets Java open source, maintenu par la Fodnation Eclipse. Connu pour sa légèreté et son efficacité, il est particulièrement prisé dans les architectures de microservices et pour l'intégration de capacités web au sein d'applications autonomes. Contrairement à des serveurs plus lourds, Jetty se distingue par sa modularité et sa faible empreinte mémoire.
Architecture et composants fondamentaux
Le fonctionnement de Jetty repose sur une structure hiérarchique simple mais puissante :
- Server : L'objet central qui coordonne le cycle de vie du serveur.
- Connectors : Ils gèrent les connexions réseau et les protocoles (HTTP, HTTPS, HTTP/2).
- Handlers : Responsables du traitement des requêtes. Jetty utilise une structure d'arborescence de gestionnaires pour router et traiter les messages entrants.
- ThreadPool : Gère les ressources d'exécution pour traiter les requêtes de manière concurrente.
// Exemple minimaliste de démarrage d'un serveur Jetty
import org.eclipse.jetty.server.Server;
public class DemarrageSimple {
public static void main(String[] args) throws Exception {
// Initialisation sur le port 9090
Server monServeurWeb = new Server(9090);
// Lancement du moteur
monServeurWeb.start();
// Maintien du thread principal en attente
monServeurWeb.join();
}
}
Installation et optimisation de la configuration
Jetty peut être utilisé en mode autonome (Standalone). Après avoir téléchargé et extrait la distribution, le répertoire etc/ contient les fichiers XML de configuration essentiels.
Le fichier jetty.xml permet de définir les propriétés globales. Par exemple, pour modifier le pool de threads et optimiser les performances sous forte charge :
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<Arg>
<New class="org.eclipse.jetty.util.thread.QueuedThreadPool">
<Set name="minThreads">20</Set>
<Set name="maxThreads">300</Set>
<Set name="idleTimeout">50000</Set>
</New>
</Arg>
</Configure>
Pour la journalisation, Jetty s'appuie souvent sur SLF4J ou Logback. La configuration se fait via le fichier resources/logback.xml, permettant de séparer les flux de logs par niveau de criticité (INFO, WARN, ERROR).
Structure d'une application Web et déploiement
Une application web Java standard suit une structure de répertoires précise pour être compatible avec Jetty :
/WEB-INF/web.xml: Le descripteur de déploiement définissant les servlets et les filtres./WEB-INF/classes: Contient les fichiers .class compilés./WEB-INF/lib: Contient les bibliothèques JAR tierces.
Exemple de déclaration de servlet dans le fichier web.xml :
<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee">
<servlet>
<servlet-name>ServiceInterne</servlet-name>
<servlet-class>com.projet.MonServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ServiceInterne</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
</web-app>
Usage de Jetty en mode embarqué
L'un des plus grands atouts de Jetty est sa capacité à être instancié directement dans le code Java. Cela élimine le besoin d'installer un serveur séparé sur la machine cible.
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
public class ServeurEmbarque {
public static void main(String[] args) throws Exception {
Server serveur = new Server(8081);
ServletContextHandler contexte = new ServletContextHandler(ServletContextHandler.SESSIONS);
contexte.setContextPath("/");
serveur.setHandler(contexte);
// Ajout d'une servlet personnalisée
contexte.addServlet(new ServletHolder(new MaServletLogique()), "/data");
serveur.start();
serveur.join();
}
}
Intégration avec Maven
L'utilisation du plugin Maven pour Jetty accélère considérablement le cycle de développement (code-test-debug) grâce au rechargement à chaud (Hot Reloading).
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.4.44.v20210927</version>
<configuration>
<scanIntervalSeconds>2</scanIntervalSeconds>
<webApp>
<contextPath>/mon-app</contextPath>
</webApp>
</configuration>
</plugin>
La commande mvn jetty:run lance alors le serveur, surveille les modifications de fichiers et redéploie l'application instantanément.
Gestion des ressources statiques et sécurité
Pour servir efficacement des fichiers CSS, JavaScript ou des images, Jetty utilise la DefaultServlet. Il est conseillé de configurer le cache pour optimiser la bande passante.
Au niveau de la sécurité, Jetty permet de restreindre l'accès à certaines ressources via des contraintes de sécurité définies programmatiquement ou dans le web.xml. L'implémentation de filtres (Filters) permet également d'intercepter les requêtes pour vérifier les jetons d'authentification ou gérer les en-têtes CORS.
Traitement des requêtes HTTP
Dans un gestionnaire Jetty, le traitement d'une requête implique la manipulation des objets HttpServletRequest et HttpServletResponse. Il est crucial de marquer la requête comme traitée pour éviter qu'elle ne soit transmise aux gestionnaires suivants dans la chaîne.
public void handle(String target, Request baseRequest,
HttpServletRequest request, HttpServletResponse response)
throws IOException {
response.setContentType("application/json;charset=utf-8");
response.setStatus(HttpServletResponse.SC_OK);
baseRequest.setHandled(true);
response.getWriter().println("{\"statut\": \"actif\"}");
}