{"id":19322737,"url":"https://github.com/gdrouet/nightclazz-spring5","last_synced_at":"2025-09-12T05:39:57.144Z","repository":{"id":150514924,"uuid":"93947463","full_name":"gdrouet/nightclazz-spring5","owner":"gdrouet","description":"Spring 5 exercices","archived":false,"fork":false,"pushed_at":"2017-09-19T08:16:19.000Z","size":71,"stargazers_count":4,"open_issues_count":0,"forks_count":4,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-22T19:45:24.234Z","etag":null,"topics":["kotlin","reactive-streams","spring-boot","spring-data-mongodb","spring-webflux"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gdrouet.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2017-06-10T15:16:59.000Z","updated_at":"2019-06-13T09:48:43.000Z","dependencies_parsed_at":"2023-04-05T00:24:25.357Z","dependency_job_id":null,"html_url":"https://github.com/gdrouet/nightclazz-spring5","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/gdrouet/nightclazz-spring5","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gdrouet%2Fnightclazz-spring5","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gdrouet%2Fnightclazz-spring5/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gdrouet%2Fnightclazz-spring5/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gdrouet%2Fnightclazz-spring5/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gdrouet","download_url":"https://codeload.github.com/gdrouet/nightclazz-spring5/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gdrouet%2Fnightclazz-spring5/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274759115,"owners_count":25343872,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-12T02:00:09.324Z","response_time":60,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["kotlin","reactive-streams","spring-boot","spring-data-mongodb","spring-webflux"],"created_at":"2024-11-10T01:42:18.519Z","updated_at":"2025-09-12T05:39:57.086Z","avatar_url":"https://github.com/gdrouet.png","language":"Java","funding_links":[],"categories":["Uncategorized"],"sub_categories":["Uncategorized"],"readme":"## Reactive Drawing Application\n\nCette application permet de se familiariser avec différentes fonctionnalités de Spring 5.\nCe fichier présente les différents exercices qui permettent de reconstruire l'application.\nLes dossiers `nc-spring-webflux` et `nc-spring-webmvc` contiennent un exemple de résultat recherché.\n\n## L'application\n\nL'application est une interface WEB de construction et partage de dessins.\nLorsque l'utilisateur se connecte, son nom lui est demandé pour démarrer un dessin.\nVia une palette, l'utilisateur dispose de différents outils pour dessiner.\nUne fois son dessin terminé, il peut ajouter son dessin à une liste contenant les dessins de tous les utilisateurs connectés à l'application.\nDès qu'un dessin est ajouté, il apparaît dans la liste des dessins de tous les utilisateurs.\n\n## Architecture\n\nLe schema d'architecture peut se présenter ainsi :\n\n```\n                     +-------------+\n                     |             |\n                +---\u003e|   MongoDB   |\u003c---+\n                |    |             |    |\n Tailable cursor|    +-------------+    | Load all images\n                |                       |\n                |                       |\n   Push new +-------------+  +-------------+\n   image ID |             |  |             |\n    +-------|   WebFlux   |  |    WebMvc   |\u003c---+\n    |       |             |  |             |    |\n    |       +-------------+  +-------------+    |\n    |                ^            ^             |\n    |     Add image  |            |HTTP/2       |\n    |     Open SSE   |            |Load statics |\n    |     connection |            |Load images  |       \n    |                |            |             |\n    |               +---------------+           |\n    |               |               |HTTP/2 push|\n    +-------------\u003e |    Browser    |-----------+\n                    |               |\n                    +---------------+\n```\n\n* Les images sont stockées dans `MongoDB` en base 64, elles seront chargées par les modules WEB\n* Un premier module est basé sur `WebFlux` correspond à l'API de l'application:\n    * Le navigateur y ouvre une connexion SSE pour recevoir les images\n    * Afin d'envoyer les URLs des images, le module `WebFlux` [crée un tailable cursor](https://docs.mongodb.com/manual/core/tailable-cursors/)\n    * Un service WEB permet l'ajout d'une nouvelle image qui sera naturellement reçue via le `tailable cursor` dès son enregistrement\n* Un second module basé sur `WebMvc` permet de servir les statics:\n    * Un service WEB permet de charger une image en fonction de son ID.\n    * Le navigateur s'y connecte en HTTP/2\n    * Lorsque la page HTML est retournée, le module utiliser le HTTP/2 `server-push` pour envoyer le contenu des images existantes\n\n## Pré-requis\n\n* Diposer d'un JDK 8\n* Avoir un accès à une instance MongoDB 3\n* Avoir une connexion internet\n* Utiliser Eclispe ou IntelliJ de préférence\n\n## Resources utiles\n\nLes ressources suivantes contiennent différents exemples qui permettent de réaliser les exercices.\nElles sont citées dans un ordre cohérent avec celui des exercices.\n\n* Spring initalizr: https://start.spring.io/\n* Reactor Getting started guide: https://github.com/reactor/reactor-core#getting-started\n* Spring WebFlux: https://spring.io/blog/2016/07/28/reactive-programming-with-spring-5-0-m1\n* WebTestClient: https://spring.io/blog/2017/02/23/spring-framework-5-0-m5-update\n* Reactive Spring Data: https://spring.io/blog/2016/11/28/going-reactive-with-spring-data\n* Reactive Mongo Template: http://docs.spring.io/spring-data/data-mongo/docs/2.0.0.M4/reference/html/#mongo.reactive.template\n* Exemple HTTP/2: https://github.com/bclozel/http2-experiments\n* Web functional framework: https://spring.io/blog/2016/09/22/new-in-spring-5-functional-web-framework\n* Kotlin support: https://spring.io/blog/2017/01/04/introducing-kotlin-support-in-spring-framework-5-0\n\n## Exercices\n\n### Le module WebFlux\n\nDans cet exercice, nous allons déclarer le contrat d'interface de l'API, les mapings et tests unitaires.\nPour initialiser le module, allez sur `spring initializr` et sélectionnez `Spring Boot 2`.\nAjoutez les modules et `Reactive Web` et `Reactive Mongo`, conservez `Maven`.\nTéléchargez l'archive ZIP et ouvrez le projet dans votre IDE.\n\nCréer les objets du domaine:\n* Une classe `DrawingInfo` annotée `@Document(collection = \"drawings\")` qui contient deux attributs de type String `id` et `author`\n* Une classe `Drawing` qui étend `DrawingInfo` avec un attribut de type String `base64Image`\n\nCréez l'interface `ReactiveDrawingController` avec les méthodes suivantes:\n\n* `Mono\u003cString\u003e add(Mono\u003cDrawing\u003e drawing)`\n* `Flux\u003cDrawingInfo\u003e getDrawings()`\n\nIl faut maintenant déclarer les mappings.\nIls se font traditionnellement avec les annotations `GetMapping`, `RequestMapping`, etc.\nNous allons plutôt utiliser un bean de type `RouterFunction` pour câbler les méthodes du contrôleur avec les URIs.\n\nCréez une classe de configuration `@Configuration` avec une méthode `@Bean public RouterFunction\u003cServerResponse\u003e routingFunction(ReactiveDrawingController)`.\nUtilisez les méthodes statiques de `RouterFunctions` pour créer deux mappings:\n\n* Un premier qui accepte une requête en `GET` sur `/drawings` et qui envoit en réponse `ReactiveDrawingController#getDrawings()` et `MediaType.TEXT_EVENT_STREAM` comme `Content-Type`.\n* Un second qui accepte une requête en `POST` sur `/drawing` qui envoit en réponse `ReactiveDrawingController#add(Mono\u003cDrawing\u003e)`. La requête et la réponse sont en `JSON`.\n\nNous allons maintenant créer des tests unitaires.\nCréez une classe de test `@SpringBootTest`.\n\nDéclarez une classe interne statique `@Configuration` dans laquelle vous créez un bean de type `ReactiveDrawingController`.\nAppuyez-vous sur `Mockito` pour retourner un `Flux` lors de l'appel de `getDrawings()`.\nPensez à importer votre classe de configuration qui créee le `RouterFunctions` via `@Import`.\n\nAvant d'écrire votre premier test, il vous faut un `WebTestClient` en tant qu'attribut.\nRegardez la [Javadoc](https://docs.spring.io/spring/docs/5.0.x/javadoc-api/org/springframework/test/web/reactive/server/WebTestClient.html) pour trouver comment créer une instance de `WebTestClient` qui tient compte de votre `RouterFunction`.\n\nEcrire une méthode `@Test` qui utilise le `WebTestClient` pour envoyer une requête sur `/drawings`.\nManipulez l'API pour vérifier que le statut de la réponse est `ok` et qu'il contient bien les éléments du `Flux` dans votre `mock`.\n\n### Le module WebMvc\n\nDans cet exercice, nous allons créer le module web qui va fournir les `statics`.\n\nPour initialiser le module, allez sur `spring initializr` et sélectionnez `Spring Boot 2`.\nAjoutez les modules et `Web` et `Reactive Mongo`, conservez `Maven`.\nTélécharger l'archive ZIP et ouvrez le projet dans votre IDE.\n\nCréez les classes du domaine `Drawing` et `DrawingInfo` comme dans `WebFlux` (on s'autorisera un peu de duplication plutôt que de créer un module commun).\n\nCréer maintenant une classe `DrawingController` et injectez dans le constructeur un `ReactiveMongoTemplate`.\n\nImplémenter un service web sur l'URI `/drawing/{id}` qui:\n* Prend en paramètre l'ID du dessin (type String)\n* Retourne un tableau de `byte` (precisez dans `@GetMapping` l'attribut `produces=MediaType.IMAGE_PNG_VALUE` et ajoutez l'annotation `ResponseBody`)\n* Utilise `ReactiveMongoTemplate#findById()` pour charger un dessin de type `Drawing` et le map en tableau de `byte`\n\nImplémentez une seconde méthode avec un mapping sur `/`:\n* Elle prend en paramètre le `PushBuilder` l'API servlet 4\n* Utilisez `ReactiveMongoTemplate#find()` pour charger la liste des dessins via le type `DrawingInfo` et effectuez un `server-push`  sur chacune des URLs d'image obtenues à partir des ID des dessins.\n* Retourne la String `drawing.html`\n\nEnfin créer une classe `@Configuration` dans laquelle vous:\n* ajoutez la vue `drawing`: https://github.com/gdrouet/nitghtclazz-spring5/blob/master/nc-spring-webmvc/src/main/java/com.zenika/WebmvcConfig.java#L22-L25\n* configurez le client `MongoDB`: https://github.com/gdrouet/nitghtclazz-spring5/blob/master/nc-spring-webmvc/src/main/java/com.zenika/WebmvcConfig.java#L43-L46\n\nDans `src/main/resources`, décompressez le contenu de cette archive: https://minhaskamal.github.io/DownGit/#/home?url=https://github.com/gdrouet/nitghtclazz-spring5/tree/master/nc-spring-webmvc/src/main/resources\nVous y trouverez:\n\n* Un répertoire `static` dont le contenu sera exposé par `Spring Boot`. C'est la partie `front` de l'application.\n* Un `application.yml` servant de base à la configuration HTTPS\n* Un `keystore` référencé dans `application.yml`\n\n`HTTP/2` ne fonctionne qu'en HTTPs. \nC'est pour cela qu'il faut avoir les éléments de configuration nécessaires à l'activation de HTTPs.\n\nA noter également que l'application envoi des requêtes vers l'API du module `WebFlux`.\nSi la page est chargée en HTTPs, alors `WebFlux` doit aussi écouter en HTTPs.\nNous allons donc également configurer HTTPs pour `WebFlux`.\n\n### Activer HTTP/2 et HTTPs\n\nTéléchargez et décompressez dans le répertoire `src/main/resources` du module `WebFlux` le contenu de cette archive: https://minhaskamal.github.io/DownGit/#/home?url=https://github.com/gdrouet/nitghtclazz-spring5/tree/master/nc-spring-webflux/src/main/resources \nVous y trouverez des informations de même nature que celles concernant HTTPs dans le répertoire du module `WebMvc`.\n\nPar défaut, `Spring Boot` doit pouvoir automatiquement configurer HTTPs avec les informations présentes, mais:\n* Avec `WebMvc` cela sera en `HTTP/1.1` alors que nous avons besoin de HTTP/2.\n* Avec `WebFlux`, l'auto-configuration en HTTPs n'est pas encore implémentée.\n\nIl faut donc substituer un bean de configuration spécifique qui accède à l'API native du conteneur de servlet.\nNous allons utiliser `Jetty` dans les deux modules.\n\nModifier le `pom.xml` de `WebFlux` comme ceci:\n\n```\n    \u003cproperties\u003e\n        \u003cjetty.version\u003e10.0.0-SNAPSHOT\u003c/jetty.version\u003e\n    \u003c/properties\u003e\n\n    ...\n\n    \u003cdependency\u003e\n        \u003cgroupId\u003eorg.springframework.boot\u003c/groupId\u003e\n        \u003cartifactId\u003espring-boot-starter-webflux\u003c/artifactId\u003e\n        \u003cexclusions\u003e\n            \u003cexclusion\u003e\n                \u003cgroupId\u003eorg.springframework.boot\u003c/groupId\u003e\n                \u003cartifactId\u003espring-boot-starter-netty\u003c/artifactId\u003e\n            \u003c/exclusion\u003e\n        \u003c/exclusions\u003e\n    \u003c/dependency\u003e\n    \u003cdependency\u003e\n        \u003cgroupId\u003eorg.springframework.boot\u003c/groupId\u003e\n        \u003cartifactId\u003espring-boot-starter-jetty\u003c/artifactId\u003e\n    \u003c/dependency\u003e\n    \n    ...\n    \n    \u003crepositories\u003e\n        \u003crepository\u003e\n            \u003cid\u003ejetty-snapshots\u003c/id\u003e\n            \u003cname\u003eJetty Snapshots\u003c/name\u003e\n            \u003curl\u003ehttps://oss.sonatype.org/content/repositories/jetty-snapshots\u003c/url\u003e\n            \u003csnapshots\u003e\n                \u003cenabled\u003etrue\u003c/enabled\u003e\n            \u003c/snapshots\u003e\n        \u003c/repository\u003e\n    \u003c/repositories\u003e\n```\n\nModifier le `pom.xml` de `WebMvc` comme ceci (il faut plus de modules pour `HTTP/2`):\n\n```\n    \u003cproperties\u003e\n        \u003cjetty.version\u003e10.0.0-SNAPSHOT\u003c/jetty.version\u003e\n        \u003c!-- https://www.eclipse.org/jetty/documentation/current/alpn-chapter.html#alpn-versions --\u003e\n        \u003calpn-version\u003e8.1.11.v20170118\u003c/alpn-version\u003e\n    \u003c/properties\u003e\n\n    ...\n\n    \u003cdependency\u003e\n        \u003cgroupId\u003eorg.springframework.boot\u003c/groupId\u003e\n        \u003cartifactId\u003espring-boot-starter-web\u003c/artifactId\u003e\n        \u003cexclusions\u003e\n            \u003cexclusion\u003e\n                \u003cgroupId\u003eorg.springframework.boot\u003c/groupId\u003e\n                \u003cartifactId\u003espring-boot-starter-tomcat\u003c/artifactId\u003e\n            \u003c/exclusion\u003e\n        \u003c/exclusions\u003e\n    \u003c/dependency\u003e\n    \u003cdependency\u003e\n        \u003cgroupId\u003ejavax.servlet\u003c/groupId\u003e\n        \u003cartifactId\u003ejavax.servlet-api\u003c/artifactId\u003e\n        \u003cversion\u003e4.0.0-b05\u003c/version\u003e\n    \u003c/dependency\u003e\n    \u003cdependency\u003e\n        \u003cgroupId\u003eorg.springframework.boot\u003c/groupId\u003e\n        \u003cartifactId\u003espring-boot-starter-jetty\u003c/artifactId\u003e\n    \u003c/dependency\u003e\n    \u003cdependency\u003e\n        \u003cgroupId\u003eorg.eclipse.jetty.http2\u003c/groupId\u003e\n        \u003cartifactId\u003ehttp2-server\u003c/artifactId\u003e\n        \u003cversion\u003e${jetty.version}\u003c/version\u003e\n    \u003c/dependency\u003e\n    \u003cdependency\u003e\n        \u003cgroupId\u003eorg.eclipse.jetty\u003c/groupId\u003e\n        \u003cartifactId\u003ejetty-alpn-server\u003c/artifactId\u003e\n        \u003cversion\u003e${jetty.version}\u003c/version\u003e\n    \u003c/dependency\u003e\n    \u003cdependency\u003e\n        \u003cgroupId\u003eorg.eclipse.jetty\u003c/groupId\u003e\n        \u003cartifactId\u003ejetty-jndi\u003c/artifactId\u003e\n        \u003cversion\u003e${jetty.version}\u003c/version\u003e\n    \u003c/dependency\u003e\n    \u003cdependency\u003e\n        \u003cgroupId\u003eorg.mortbay.jetty.alpn\u003c/groupId\u003e\n        \u003cartifactId\u003ealpn-boot\u003c/artifactId\u003e\n        \u003cversion\u003e${alpn-version}\u003c/version\u003e\n        \u003cscope\u003eprovided\u003c/scope\u003e\n    \u003c/dependency\u003e\n    \n    ...\n    \n    \u003crepositories\u003e\n        \u003crepository\u003e\n            \u003cid\u003ejetty-snapshots\u003c/id\u003e\n            \u003cname\u003eJetty Snapshots\u003c/name\u003e\n            \u003curl\u003ehttps://oss.sonatype.org/content/repositories/jetty-snapshots\u003c/url\u003e\n            \u003csnapshots\u003e\n                \u003cenabled\u003etrue\u003c/enabled\u003e\n            \u003c/snapshots\u003e\n        \u003c/repository\u003e\n    \u003c/repositories\u003e\n```\n\nNotez que nous utilisons la version 10 de `Jetty`, toujours en `snapshot`.\nCela nous permettra d'exploiter l'API servlet 4 afin de faire du `server-push` avec `HTTP/2`.\nRegardez également la version utilisée pour `ALPN` et assurez-vous qu'elle est compatible avec votre JDK.\n\nIl faut maintenant déclarer les beans de configuration.\nPour `WebFlux`, il faut configurer un `ReactiveWebServerFactory`:\n* https://github.com/gdrouet/nitghtclazz-spring5/blob/master/nc-spring-webflux/src/main/java/com/zenika/config/ReactiveWebServerFactoryConfig.java\n* https://github.com/gdrouet/nitghtclazz-spring5/blob/master/nc-spring-webflux/src/main/java/com/zenika/config/CustomJettyReactiveWebServerFactory.java\n\nPour `WebMvc`, on peut passer par un `WebServerFactoryCustomizer`:\n* https://github.com/gdrouet/nitghtclazz-spring5/blob/master/nc-spring-webmvc/src/main/java/com.zenika/JettyHttp2Customizer.java\n* https://github.com/gdrouet/nitghtclazz-spring5/blob/master/nc-spring-webmvc/src/main/java/com.zenika/WebmvcConfig.java#L33-L36\n\n### Lancer WebMvc\n\nNous allons maintenant configurer les pramaètres de lancement de `WebMvc`.\nDans votre IDE, ajustez les options de la JVM avec le chemin du JAR ALPN:\n`-Xbootclasspath/p:\u003c\u003cMAVEN_LCOAL_REPO\u003e\u003e/org/mortbay/jetty/alpn/alpn-boot/\u003c\u003cversion\u003e\u003e/alpn-boot-\u003c\u003cversion\u003e\u003e.jar`\n\nNous allons également passer en argument les informations nécessaires pour écouter sur le port `8443` et se connecter à `MongoDB`.\n* `--spring.data.mongodb.uri=mongodb://\u003c\u003cuser\u003e\u003e:\u003c\u003cpassword\u003e\u003e@\u003c\u003chost\u003e\u003e:\u003c\u003cport\u003e\u003e/\u003c\u003cdatabase\u003e\u003e`\n* `--server.port=8443`\n\nA ce stade, vous devriez pouvoir démarrer le module `WebMvc`.\nNéanmoins, l'application doit s'appuyer sur le module `WebFlux`.\nNous allons maintenant le démarrer.\n\n### Lancer WebFlux\n\nLe module est correctement configuré pour écouter en HTTPs.\nNous avons néanmoins deux problèmes que nous allons traiter:\n\n* `ReactiveDrawingController` n'est pas implémenté (il a été bouchonné pour les tests unitaires)\n* Les requêtes envoyées par le navigateur viennent d'un port différent, il faut configurer le `CORS`\n \nCréez une classe `ReactiveDrawingControllerImpl`.\nAssurez-vous qu'elle est bien injectée dans le contexte Spring tout en étant ignorée dans les tests unitaires.\n\nVous devez injecter dans votre contrôleur un bean qui étend `ReactiveCrudRepository` afin de récupérer et sauvegarder les dessins.\nPour ce faire, créez une interface `DrawingRepository` qui étend `ReactiveCrudRepository`.\nCe dernier peut être spécialisé pour les dessins, référez-vous à la Javadoc afin de savoir comment configurer vos generics.\nPour la sauvegarde, vous disposez d'un `Mono\u003cDrawing\u003e` en paramètre de la méthode `add` du contrôleur qui peut être utilisé dans une méthode `saveAll` du `ReactiveCrudRepository`.\nPour récupérer les dessins dans un flux continu qui alimentera la connexion SSE, vous devez utiliser un `tailable cursor`.\nAjoutez dans votre `DrawingRepository` une méthode qui retournera un `Flux` qui est annotée `@Tailable`.\n\nIl faut à présent configurer le `CORS` pour que des requêtes depuis `https://localhost:8443` soit acceptées.\nLe protocole HTTP prévoit d'envoyer une requête `OPTIONS` afin de savoir quelles requêtes seront acceptées.\nDans votre bean de configuration des routes, faites en sorte qu'une requête sur `/drawing*` avec la méthode `OPTIONS` soit `ok`.\n\nCréez ensuite une nouvelle classe de configuration annotée `@EnableWebFlux` qui implémente `WebFluxConfigurer`.\nSurchargez `addCorsMappings(CorsRegistry)` et utilisez le registre pour faire les configurations suivantes:\n* Méthode `GET` autorisée sur `/drawings`\n* Méthode `POST` autorisée sur `/drawing`\n* `https://localhost:8443` comme origine autorisée sur `/drawings` et `/drawing`\n* `Content-Type` comme header autorisée sur `/drawings` et `/drawing`\n\nIl ne reste plus qu'à lancer le module `WebFlux`.\nConfigurer votre IDE pour passer les arguments suivants;\n* `--spring.data.mongodb.uri=mongodb://\u003c\u003cuser\u003e\u003e:\u003c\u003cpassword\u003e\u003e@\u003c\u003chost\u003e\u003e:\u003c\u003cport\u003e\u003e/\u003c\u003cdatabase\u003e\u003e`\n* `--server.port=9443`\n\nConnectez-vous à présent sur https://localhost:8443 et testez l'application!\n\n### Kotlin\n\nNous allons maintenant utiliser le language Kotlin pour déclarer nos routes de façon plus concise.\nDu code Java et Kotlin peuvent tout à fait cohabiter ensemble.\n\nDans le `pom.xml` du module `WebFlux`, déclarez les éléments suivants:\n\n```\n\u003cproperties\u003e\n    \u003ckotin.version\u003e1.1.2-5\u003c/kotin.version\u003e\n\u003c/properties\u003e\n\n...\n\n\u003cdependencies\u003e\n    \u003cdependency\u003e\n        \u003cgroupId\u003eorg.jetbrains.kotlin\u003c/groupId\u003e\n        \u003cartifactId\u003ekotlin-stdlib-jre8\u003c/artifactId\u003e\n        \u003cversion\u003e${kotlin.version}\u003c/version\u003e\n    \u003c/dependency\u003e\n    \u003cdependency\u003e\n        \u003cgroupId\u003eorg.jetbrains.kotlin\u003c/groupId\u003e\n        \u003cartifactId\u003ekotlin-test\u003c/artifactId\u003e\n        \u003cversion\u003e${kotlin.version}\u003c/version\u003e\n        \u003cscope\u003etest\u003c/scope\u003e\n    \u003c/dependency\u003e\n\u003c/dependencies\u003e\n\n...\n\n\u003cbuild\u003e\n    \u003csourceDirectory\u003e${project.basedir}/src/main/kotlin\u003c/sourceDirectory\u003e\n    \u003cplugins\u003e\n        \u003cplugin\u003e\n            \u003cartifactId\u003ekotlin-maven-plugin\u003c/artifactId\u003e\n            \u003cexecutions\u003e\n                \u003cexecution\u003e\n                    \u003cid\u003ecompile\u003c/id\u003e\n                    \u003cphase\u003ecompile\u003c/phase\u003e\n                    \u003cgoals\u003e\n                        \u003cgoal\u003ecompile\u003c/goal\u003e\n                    \u003c/goals\u003e\n                    \u003cconfiguration\u003e\n                        \u003csourceDirs\u003e\n                            \u003csource\u003esrc/main/java\u003c/source\u003e\n                            \u003csource\u003esrc/main/kotlin\u003c/source\u003e\n                        \u003c/sourceDirs\u003e\n                    \u003c/configuration\u003e\n                \u003c/execution\u003e\n                \u003cexecution\u003e\n                    \u003cid\u003etest-compile\u003c/id\u003e\n                    \u003cphase\u003etest-compile\u003c/phase\u003e\n                    \u003cgoals\u003e\n                        \u003cgoal\u003etest-compile\u003c/goal\u003e\n                    \u003c/goals\u003e\n                \u003c/execution\u003e\n            \u003c/executions\u003e\n            \u003cgroupId\u003eorg.jetbrains.kotlin\u003c/groupId\u003e\n            \u003cversion\u003e${kotlin.version}\u003c/version\u003e\n        \u003c/plugin\u003e\n        \u003cplugin\u003e\n            \u003cgroupId\u003eorg.apache.maven.plugins\u003c/groupId\u003e\n            \u003cartifactId\u003emaven-compiler-plugin\u003c/artifactId\u003e\n            \u003cexecutions\u003e\n                \u003cexecution\u003e\n                    \u003cid\u003edefault-compile\u003c/id\u003e\n                    \u003cphase\u003enone\u003c/phase\u003e\n                \u003c/execution\u003e\n                \u003cexecution\u003e\n                    \u003cid\u003edefault-testCompile\u003c/id\u003e\n                    \u003cphase\u003enone\u003c/phase\u003e\n                \u003c/execution\u003e\n                \u003cexecution\u003e\n                    \u003cid\u003ecompile\u003c/id\u003e\n                    \u003cphase\u003ecompile\u003c/phase\u003e\n                    \u003cgoals\u003e\n                        \u003cgoal\u003ecompile\u003c/goal\u003e\n                    \u003c/goals\u003e\n                \u003c/execution\u003e\n                \u003cexecution\u003e\n                    \u003cid\u003etestCompile\u003c/id\u003e\n                    \u003cphase\u003etest-compile\u003c/phase\u003e\n                    \u003cgoals\u003e\n                        \u003cgoal\u003etestCompile\u003c/goal\u003e\n                    \u003c/goals\u003e\n                \u003c/execution\u003e\n            \u003c/executions\u003e\n        \u003c/plugin\u003e\n    \u003c/plugins\u003e\n\u003c/build\u003e\n```\n\nCommentez votre classe `RouteConfig` et ajoutez une classe `RouteConfig.kt` dans `/src/main/kotlin`.\nEssayez de réécrire les différentes méthodes de votre classe de configuration Java en Kotlin.\nInspirez-vous des ressources citées plus haut afin de trouver des élémens syntaxiques qui pourront vous aider.\n\nSi vous disposez de `IntelliJ`, un support avancé du language est proposé.\nLorsque vous copier/coller du code Java dans une classe Kotlin, l'IDE peut vous convertire relatvement efficacement le code.\n\nUne fois terminé testez de nouveau l'application.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgdrouet%2Fnightclazz-spring5","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgdrouet%2Fnightclazz-spring5","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgdrouet%2Fnightclazz-spring5/lists"}