Introduction à ActiveWeb
1. Vue d'ensemble
Dans cet article, nous allons illustrer leActiveweb - un framework Web complet de JavaLite - fournissant tout le nécessaire pour le développement d'applications Web dynamiques ou de services Web REST-ful.
2. Concepts et principes de base
Activeweb tire parti de la «convention sur la configuration» - ce qui signifie qu’il est configurable, mais a des valeurs par défaut raisonnables et ne nécessite pas de configuration supplémentaire. Nous devons simplement suivre quelques conventions prédéfinies, telles que la dénomination de classes, de méthodes et de champs dans un certain format prédéfini.
Cela simplifie également le développement en recompilant et en rechargeant la source dans le conteneur en cours d'exécution (Jetty par défaut).
Pour la gestion des dépendances, il utilise Google Guice comme framework DI; pour en savoir plus sur Guice, jetez un œil à nosguide here.
3. Maven Setup
4. Structure d'application
Comme nous l'avons vu, la structure de l'application doit suivre une certaine convention; voici à quoi cela ressemble pour une application MVC typique:
Comme nous pouvons le voir,controllers,service,config etmodels doivent être situés dans leur propre sous-package dans le packageapp.
Les vues doivent être situées dans le répertoireWEB-INF/views, chacune ayant son propre sous-répertoire basé sur le nom du contrôleur. Par exemple,app.controllers.ArticleController doit avoir un sous-répertoirearticle/ contenant tous les fichiers de vue pour ce contrôleur.
Le descripteur de déploiement ou lesweb.xml doivent généralement contenir un<filter> et le<filter-mapping>. correspondant. Puisque le framework est un filtre de servlet, au lieu d'une configuration<servlet>, il existe une configuration de filtre:
...
dispatcher
org.javalite.activeweb.RequestDispatcher
...
...
Nous avons également besoin d'un<init-param>root_controller pour définir le contrôleur par défaut de l'application - semblable à un contrôleurhome:
...
root_controller
home
...
5. Contrôleurs
Les contrôleurs sont les principaux composants d'une application ActiveWeb; et, comme mentionné précédemment, tous les contrôleurs doivent être situés dans le packageapp.controllers:
public class ArticleController extends AppController {
// ...
}
Notez que le contrôleur étendorg.javalite.activeweb.AppController.
5.1. Mappage d'URL du contrôleur
Les contrôleurs sont automatiquement mappés sur une URL en fonction de la convention. Par exemple,ArticleController sera mappé sur:
http://host:port/contextroot/article
Maintenant, cela les mettrait en correspondance avec l'action par défaut du contrôleur. Les actions ne sont que des méthodes à l'intérieur du contrôleur. Nommez la méthode par défaut commeindex():
public class ArticleController extends AppController {
// ...
public void index() {
render("articles");
}
// ...
}
Pour les autres méthodes ou actions, ajoutez le nom de la méthode à l'URL:
public class ArticleController extends AppController {
// ...
public void search() {
render("search");
}
}
L'URL:
http://host:port/contextroot/article/search
Nous pouvons même avoir des actions de contrôleur basées sur des méthodes HTTP. Annotez simplement la méthode avec l'un ou l'autre des@POST, @PUT, @DELETE, @GET, @HEAD.. Si nous n'annotons pas une action, elle est considérée comme un GET par défaut.
5.2. Résolution d'URL du contrôleur
L'infrastructure utilise le nom du contrôleur et le nom du sous-package pour générer l'URL du contrôleur. Par exempleapp.controllers.ArticleController.java l'URL:
http://host:port/contextroot/article
Si le contrôleur est à l'intérieur d'un sous-package, l'URL devient simplement:
http://host:port/contextroot/example/article
Pour un nom de contrôleur ayant plus d'un mot (par exempleapp.controllers.PublishedArticleController.java), l'URL sera séparée par un trait de soulignement:
http://host:port/contextroot/published_article
5.3. Récupération des paramètres de demande
À l'intérieur d'un contrôleur, nous avons accès aux paramètres de la requête en utilisant les méthodesparam() ouparams() desAppController class. La première méthode prend un argument String - le nom du paramètre à récupérer:
public void search() {
String keyword = param("key");
view("search",articleService.search(keyword));
}
Et nous pouvons utiliser le dernier pour obtenir tous les paramètres si nous devons:
public void search() {
Map criterion = params();
// ...
}
6. Vues
Dans la terminologie ActiveWeb, les vues sont souvent appelées modèles; ceci est principalement dû au fait qu'il utilise le moteur de modèle ApacheFreeMarkerau lieu des JSP. Vous pouvez en savoir plus sur FreeMarkerin our guide, here.
Placez les modèles dans le répertoireWEB-INF/views. Chaque contrôleur devrait avoir un sous-répertoire par son nom contenant tous les modèles requis.
6.1. Mappage de la vue du contrôleur
Lorsqu'un contrôleur est touché, l'action par défautindex() est exécutée et le framework choisit le modèleWEB-INF/views/article/index.ftl dans le répertoire from views pour ce contrôleur. De même, pour toute autre action, la vue serait choisie en fonction du nom de l'action.
Ce n’est pas toujours ce que nous souhaitons. Parfois, nous pouvons vouloir renvoyer des vues basées sur une logique métier interne. Dans ce scénario,we can control the process with the render() method de la classe parentorg.javalite.activeweb.AppController:
public void index() {
render("articles");
}
Notez que l'emplacement des vues personnalisées doit également se trouver dans le même répertoire de vues pour ce contrôleur. Si ce n'est pas le cas, préfixez le nom du modèle avec le nom du répertoire où réside le modèle et passez-le à la méthoderender():
render("/common/error");
6.3. Vues avec données
Pour envoyer des données aux vues, leorg.javalite.activeweb.AppController fournit la méthodeview():
view("articles", articleService.getArticles());
Cela prend deux paramètres. Tout d'abord, le nom de l'objet utilisé pour accéder à l'objet dans le modèle et ensuite un objet contenant les données.
Nous pouvons également utiliser la méthodeassign() pour transmettre des données aux vues. Il n'y a absolument aucune différence entre les méthodes view () etassign() - nous pouvons choisir l'une d'entre elles:
assign("article", articleService.search(keyword));
Mappons les données dans le modèle:
<@content for="title">Articles@content>
...
<#list articles as article>
${article.title}
${article.author}
${article.words}
${article.date}
#list>
7. Gérer les dépendances
Pour gérer les objets et les instances, ActiveWeb utilise Google Guice comme infrastructure de gestion des dépendances.
Disons que nous avons besoin d'une classe de service dans notre application; cela séparerait la logique métier des contrôleurs.
Commençons par créer une interface de service:
public interface ArticleService {
List getArticles();
Article search(String keyword);
}
Et la mise en place:
public class ArticleServiceImpl implements ArticleService {
public List getArticles() {
return fetchArticles();
}
public Article search(String keyword) {
Article ar = new Article();
ar.set("title", "Article with "+keyword);
ar.set("author", "example");
ar.set("words", "1250");
ar.setDate("date", Instant.now());
return ar;
}
}
Maintenant, lions ce service en tant que module Guice:
public class ArticleServiceModule extends AbstractModule {
@Override
protected void configure() {
bind(ArticleService.class).to(ArticleServiceImpl.class)
.asEagerSingleton();
}
}
Enfin, enregistrez-le dans le contexte de l'application et injectez-le dans le contrôleur, comme requis:
public class AppBootstrap extends Bootstrap {
public void init(AppContext context) {
}
public Injector getInjector() {
return Guice.createInjector(new ArticleServiceModule());
}
}
Notez que ce nom de classe de configuration doit êtreAppBootstrap et doit être situé dans le packageapp.config.
Enfin, voici comment nous l'injectons dans le contrôleur:
@Inject
private ArticleService articleService;
8. Essai
Les tests unitaires pour une application ActiveWeb sont écrits à l'aide de la bibliothèqueJSpec de JavaLite.
Nous utiliserons la classeorg.javalite.activeweb.ControllerSpec de JSpec pour tester notre contrôleur, et nous nommerons les classes de test selon une convention similaire:
public class ArticleControllerSpec extends ControllerSpec {
// ...
}
Notez que le nom est similaire à celui du contrôleur qu’il teste avec un «Spec» à la fin.
Voici le cas de test:
@Test
public void whenReturnedArticlesThenCorrect() {
request().get("index");
a(responseContent())
.shouldContain("Introduction to Mule ");
}
Notez que la méthoderequest() simule l'appel au contrôleur et que la méthode HTTP correspondanteget(), prend le nom de l'action comme argument.
Nous pouvons également passer des paramètres au contrôleur en utilisant la méthodeparams():
@Test
public void givenKeywordWhenFoundArticleThenCorrect() {
request().param("key", "Java").get("search");
a(responseContent())
.shouldContain("Article with Java ");
}
Pour transmettre plusieurs paramètres, nous pouvons également chaîner la méthode, avec cette API fluide.
9. Déploiement de l'application
Il est possible de déployer l’application dans n’importe quel conteneur de servlet comme Tomcat, WildFly ou Jetty. Bien sûr, le moyen le plus simple de déployer et de tester serait d'utiliser le plugin Maven Jetty:
...
org.eclipse.jetty
jetty-maven-plugin
9.4.8.v20171121
manual
10000
...
La dernière version du plugin esthere.
Maintenant, enfin - nous pouvons le lancer:
mvn jetty:run
10. Conclusion
Dans cet article, nous avons appris les concepts de base et les conventions du framework ActiveWeb. En plus de cela, le framework a plus de fonctionnalités et de capacités que ce dont nous avons discuté ici.
Veuillez consulter lesdocumentationofficiels pour plus de détails.
Et, comme toujours, l'exemple de code utilisé dans l'article est disponibleover on GitHub.