JEP408 Un Simple Serveur Web en java
MAJ 2022-01 : La version finale de la JEP a été intégré dans le JDK 18. Des changements ont été apportées. Plus d’informations sur le billet consacré
Contexte
Nous allons nous projeter dans le futur en étudiant cette JEP, candidate pour le JDK 17. Le but est de mettre à disposition un petit serveur web qui renvoie simplement des pages statiques. Lors du développement web, il peut être intéressant d’avoir un serveur web pour
-
renvoyer des pages statiques (comme une page html chargeant des scripts javascript)
-
renvoyer des réponses JSON d’exemples pour tester la communication avec une autre API
Donc, l’idée est que le developpeur Java soit aussi pourvu que les développeurs d’autres langages.
Ligne de commande
Pour démarrer le serveur, il suffit de taper la commande suivante :
java -m jdk.httpserver
Nous obtenons le message suivant :
Serving /current/directory on http://127.0.0.1:8000/
Des options seront disponibles :
-
(-b) pour préciser l’interface réseau
-
(-p) pour préciser le numéro de port
-
(-h) pour afficher le message d’aide
-
(-o : none | default | verbose) pour afficher des informations lors de traitement des requêtes
En activant la journalisation, nous obtenons pour chaque requête le message équivalent :
127.0.0.1 - - [10/Feb/2021:14:34:11 +0000] "GET /some/subdirectory/" 200
Cela veut dire que ce n’est pas une commande supplémentaire. Nous utilisons tout simplement la JVM.
Implémentation
L’idée serait d’utiliser le module jdk.httpserver
qui contient l’API public com.sun.net.httpserver
.
Le serveur répondrait uniquement aux méthodes HEAD et GET (requêtes idempotentes).
API
Le principe serait d’avoir une classe SimpleFileServer
ayant l’interface suivante :
package com.sun.net.httpserver;
public final class SimpleFileServer {
public static HttpServer createFileServer(int port, Path root,
OutputLevel outputLevel) {...}
public static HttpHandler createFileHandler(Path root) {...}
public static Filter createOutputFilter(OutputStream out,
OutputLevel outputLevel) {...}
...
}
En utilisant la commande jshell
, il suffirait d’écrire
jshell> var server = SimpleFileServer.createFileServer(8080,
...> Path.of("/some/path"), OutputLevel.VERBOSE);
jshell> server.start()
Cela est simple et efficace.
Pour autant, il serait possible d’étendre le comportement de base en créeant notre propre serveur en passant notre intance de HttpHandler
public static HttpServer create(InetSocketAddress addr,
int backlog,
String root,
HttpHandler handler,
Filter... filters) throws IOException {...}
Cette dernière pourrait être construite à partir de la classe suivante :
package com.sun.net.httpserver;
public class HttpHandlers {
public static HttpHandler handleOrElse(Predicate<Request> handlerTest,
HttpHandler handler,
HttpHandler fallbackHandler)
throws IOException {...}
public static HttpHandler adaptRequest(HttpHandler handler,
UnaryOperator<Request> operator)
{...}
}
D’autres alternatives seront envisagées pendant la phase de prototypage.
Dans tous les cas, j’ai hâte de pouvoir jouer avec !
Références
Moteur de recherche
"Eduquer, ce n'est pas remplir des vases mais c'est d'allumer des feux." - Michel Montaigne
Billets récents
- Eclipse plante systématiquement sous Debian (et autres distribution Linux)
- JEP 463, Implicitly Declared Classes and Instance Main Methods (Second Preview)
- Debian - Montée de version de Debian 11 (Bullseye) à Debian 12 (Bookworm)
- JEP 451, Prepare to Disallow the Dynamic Loading of Agents
- JEP 444, Virtual Threads