Introduction à Jooby

1. Vue d'ensemble

Jooby est un micro-framework Web évolutif et rapide construit sur les serveurs Web NIO les plus utilisés . C'est très simple et modulaire, clairement conçu pour l'architecture Web moderne. Il est également compatible avec Javascript et Kotlin .

Par défaut, Jooby est fourni avec un excellent support pour Netty, Jetty et Undertow .

Dans cet article, nous allons découvrir la structure globale du projet Jooby et comment créer une application Web simple à l'aide de Jooby .

2. Architecture d'application

Une structure d'application Jooby simple sera comme ci-dessous:

├── public | └── welcome.html ├── conf | ├── application.conf | └── logback.xml └── src | ├── main | | └── java | | └── com | | └── baeldung | | └── jooby | | └── App.java | └── test | └── java | └── com | └── baeldung | └── jooby | └── AppTest.java ├── pom.xml

Le point à noter ici est que dans le répertoire public , nous pouvons mettre des fichiers statiques comme css / js / html etc. Dans le répertoire conf , nous pouvons mettre n'importe quel fichier de configuration dont une application a besoin comme logback.xml ou application.conf etc.

3. Dépendance de Maven

Nous pouvons créer une application Jooby simple en ajoutant la dépendance suivante dans notre pom.xml:

 org.jooby jooby-netty 1.1.3 

Si nous voulons choisir Jetty ou Undertow, nous pouvons utiliser la dépendance suivante:

 org.jooby jooby-jetty 1.1.3   org.jooby jooby-undertow 1.1.3 

Vous pouvez vérifier la dernière version du projet Jooby dans le référentiel central Maven.

Jooby possède également un archétype Maven dédié. Nous pouvons l'utiliser pour créer un exemple de projet avec toutes les dépendances nécessaires pré-construites.

Nous pouvons utiliser le script suivant pour générer l'exemple de projet:

mvn archetype:generate -B -DgroupId=com.baeldung.jooby -DartifactId=jooby -Dversion=1.0 -DarchetypeArtifactId=jooby-archetype -DarchetypeGroupId=org.jooby -DarchetypeVersion=1.1.3

4. Création d'une application

4.1. Lancement du serveur

Pour démarrer le serveur intégré, nous devons utiliser l'extrait de code suivant:

public class App extends Jooby { public static void main(String[] args) { run(App::new, args); } }

Une fois démarré, le serveur fonctionnera sur le port par défaut 8080 .

Nous pouvons également configurer le serveur principal avec un port personnalisé et un port HTTPS personnalisé :

{ port( 8081 ); securePort( 8443 ); }

4.2. Implémentation du routeur

Il est très facile de créer un routeur basé sur un chemin dans Jooby . Par exemple, nous pouvons créer un routeur pour le chemin ' / login ' de la manière suivante:

{ get( "/login", () -> "Hello from Baeldung"); }

De la même manière, si nous voulons gérer d'autres méthodes HTTP comme POST, PUT, etc., nous pouvons utiliser l'extrait de code ci-dessous:

{ post( "/save", req -> { Mutant token = req.param( "token" ); return token.intValue(); }); }

Ici, nous récupérons le jeton de nom de paramètre de requête à partir de la requête. Par défaut, tous les paramètres de requête sont transtypés dans le type de données Mutant de Jooby . En fonction de l'attente, nous pouvons le convertir en n'importe quel type de données primitif pris en charge.

Nous pouvons vérifier n'importe quel paramètre d'URL de la manière suivante:

{ get( "/user/{id}", req -> "Hello user : " + req.param("id").value() ); get( "/user/:id", req -> "Hello user: " + req.param("id").value() ); }

Nous pouvons utiliser n'importe lequel des éléments ci-dessus. Il est également possible de trouver des paramètres commençant par un contenu fixe. Par exemple, nous pouvons trouver un paramètre d'URL commençant par ' uid:' de la manière suivante:

{ get( "/uid:{id}", req -> "Hello User with id : uid" + req.param("id").value()); }

4.3. Implémentation du contrôleur de modèle MVC

Pour une application d'entreprise, Jooby est livré avec une API MVC un peu comme n'importe quel autre framework MVC comme Spring MVC.

Par exemple, nous pouvons gérer un chemin appelé ' / hello ':

@Path("/hello") public class GetController { @GET public String hello() { return "Hello Baeldung"; } }

De la même manière, nous pouvons créer un gestionnaire pour gérer d'autres méthodes HTTP avec l' annotation @POST, @PUT, @DELETE , etc.

4.4. Gestion du contenu statique

Pour servir tout contenu statique tel que HTML, Javascript, CSS, image, etc., nous devons placer ces fichiers dans le répertoire public .

Une fois placé, à partir du routeur, nous pouvons mapper n'importe quelle URL à ces ressources:

{ assets( "/employee" , "form.html" ); }

4.5. Formulaire de traitement

L' interface Request de Jooby gère par défaut tout objet de formulaire sans utiliser de conversion de type manuelle.

Supposons que nous devions soumettre les détails des employés via un formulaire. Dans un premier temps, nous devons créer un objet bean Employee que nous utiliserons pour contenir les données:

public class Employee { String id; String name; String email; // standard constructors, getters and setters }

Maintenant, nous devons créer une page pour créer le formulaire:

Ensuite, nous allons créer un gestionnaire de publication pour adresser ce formulaire et récupérer les données soumises:

post( "/submitForm", req -> { Employee employee = req.params(Employee.class); // ... return "empoyee data saved successfullly"; });

Point à noter ici est que nous devons déclarer besoin sous forme enctype comme application / x-www-form-urlencoded pour soutenir la forme de liaison dynamique.

Par Request.file (String filename), nous pouvons récupérer le fichier téléchargé:

post( "/upload", req -> { Upload upload = req.file("file"); // ... upload.close(); });

4.6. Implémentation d'un filtre

Hors de la boîte , Jooby offre la possibilité de définir des filtres globaux ainsi que les filtres basés sur la route.

Implementing filter in Jooby is a little bit tricky since we need to configure the URL path twice, once for the filter and once again for the handler.

For example, if we have to implement a filter for a URL path called ‘/filter', we need to implement the filter in this path explicitly:

get( "/filter", ( req, resp, chain ) -> { // ... chain.next( req, resp ); });

The syntax is very similar to Servlet filter. It's possible to restrict the request and send back the response in the filter itself by calling Response.send(Result result) method.

Once the filter is implemented, we need to implement the request handler:

get("/filter", (req, resp) -> { resp.send("filter response"); });

4.7. Session

Jooby comes with two types of session implementation; in-memory and cookie-based.

Implementing in-memory session management is quite simple. We have the options to choose any of the high-throughput session stores available with Jooby like EhCache, Guava, HazleCast, Cassandra, Couchbase, Redis, MongoDB, and Memcached.

For example, to implement a Redis-based session storage, we need to add following Maven dependency:

 org.jooby jooby-jedis 1.1.3 

Now we can use below code snippet to enable session management:

{ use(new Redis()); session(RedisSessionStore.class); get( "/session" , req -> { Session session = req.session(); session.set("token", "value"); return session.get("token").value(); }); }

Point to note here is that we can configure Redis url as the ‘db' property in the application.conf.

To enable cookie based session management, we need to declare cookieSession(). If cookie based approach is selected, we must need to declare application.secret property in the application.conf file. Since each cookie will be signed will be signed with this secret key, it's always advisable to use long random string fragment as a secret key.

In both in-memory and cookie based approach, we must have to declare the necessary configuration parameter in the application.conf file, else the application will throw an IllegalStateException at start up.

5. Testing

Testing MVC route is indeed easy since a route is bound to a strategy for some class. This makes it easy to run unit tests against all routes.

For example, we can quickly create a test-case for default URL:

public class AppTest { @ClassRule public static JoobyRule app = new JoobyRule(new App()); @Test public void given_defaultUrl_expect_fixedString() { get("/").then().assertThat().body(equalTo("Hello World!")) .statusCode(200).contentType("text/html;charset=UTF-8"); } }

Point to note here is that using @ClassRule annotation will create only one instance of the server for all test-cases. If we need to build separate instances of the servers for every test-cases we have to use the @Rule annotation without the static modifier.

We can also use Jooby's MockRouter to test the path in the same way:

@Test public void given_defaultUrl_with_mockrouter_expect_fixedString() throws Throwable { String result = new MockRouter(new App()).get("/"); assertEquals("Hello World!", result); }

6. Conclusion

In this tutorial, we explored the Jooby project and its essential functionality.

Like always, the full source code is available over on GitHub.