BT

Diffuser les Connaissances et l'Innovation dans le Développement Logiciel d'Entreprise

Contribuez

Sujets

Sélectionner votre région

Accueil InfoQ Articles Comment Créer Facilement Votre Application Java Avec JSF

Comment Créer Facilement Votre Application Java Avec JSF

Favoris

Points Clés

  • Introduire les bases de Jakarta Server Faces
  • Comprendre le rôle et la porter des Managed Beans
  • Comprendre l'integration entre JSF et Jakarta NoSQL
  • Coder l'interface graphique avec PrimeFaces
  • Stocker l'application dans GitHub
  • Construire et déployer l'application dans le cloud grâce à Platform.sh

Le développement d'applications web est une réalité sur le marché actuel, et le framework Jakarta Server Faces (JSF) est une option standard de Jakarta EE pour résoudre à ce type de problématique. L'une des caractéristiques de JSF est de travailler de manière orientée vers les composants graphiques et leurs événements (par exemple, les clics). De cette façon, nous pouvons associer ces composants à différents aspects de notre système, comme l'exécution de traitements métier, les conversions de valeurs, les validations de champs, etc. Dans cet article, nous parlerons de JSF et de comment déployer une application sur le cloud avec Platform.sh.

Pour illustrer JSF dans cet article, créons une petite liste de souhaits en Java avec les technologies de Jakarta EE. En front-end, nous utiliserons Jakarta Server Faces (JSF), un framework d'applications web basé sur Java qui simplifie l'intégration des interfaces utilisateur web dans le développement avec plusieurs composants déjà réalisés. Pour stocker la liste, nous utiliserons la base de données MongoDB.

Jakarta Server Faces définit un framework MVC pour la création d'interfaces utilisateur pour les applications web, y compris les composants de l'interface utilisateur, la gestion des états, le traitement des événements, la validation des entrées, la navigation des pages et le support de l'internationalisation et à l'accessibilité.

Comme pour tout projet Maven, la première étape consiste à définir les dépendances que l'application requiert. Pour cette application JSF et MongoDB sur la pile de Jakarta EE, nous utiliserons JSF, Jakarta NoSQL et Primefaces. Primefaces est une bibliothèque open source de composants d'interface utilisateur (UI) pour les applications basées sur JSF.


<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>sh.platform.template</groupId>
    <artifactId>microprofile-thorntail</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>war</packaging>
    <properties>
        <version.thorntail>2.6.0.Final</version.thorntail>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <failOnMissingWebXml>false</failOnMissingWebXml>
        <platform.sh.version>2.2.3</platform.sh.version>
        <jakarta.nosql.version>1.0.0-b1</jakarta.nosql.version>
        <junit.version>5.5.2</junit.version>
        <maven.surefire.plugin.version>2.22.2</maven.surefire.plugin.version>
        <test.containers.version>1.12.0</test.containers.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>io.thorntail</groupId>
                <artifactId>bom-all</artifactId>
                <version>${version.thorntail}</version>
                <scope>import</scope>
                <type>pom</type>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>io.thorntail</groupId>
            <artifactId>jsf</artifactId>
        </dependency>
        <dependency>
            <groupId>io.thorntail</groupId>
            <artifactId>cdi</artifactId>
        </dependency>
        <dependency>
            <groupId>sh.platform</groupId>
            <artifactId>config</artifactId>
            <version>${platform.sh.version}</version>
        </dependency>
        <dependency>
            <groupId>org.eclipse.jnosql.artemis</groupId>
            <artifactId>artemis-document</artifactId>
            <version>${jakarta.nosql.version}</version>
        </dependency>
        <dependency>
            <groupId>org.eclipse.jnosql.diana</groupId>
            <artifactId>mongodb-driver</artifactId>
            <version>${jakarta.nosql.version}</version>
        </dependency>
        <dependency>
            <groupId>org.primefaces</groupId>
            <artifactId>primefaces</artifactId>
            <version>7.0</version>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-params</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.testcontainers</groupId>
            <artifactId>testcontainers</artifactId>
            <version>${test.containers.version}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <finalName>wish</finalName>
        <plugins>
            <plugin>
                <groupId>io.thorntail</groupId>
                <artifactId>thorntail-maven-plugin</artifactId>
                <version>${version.thorntail}</version>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>${maven.surefire.plugin.version}</version>
            </plugin>
        </plugins>
    </build>
</project>

La prochaine étape est l'intégration de MongoDB ; nous n'irons pas plus loin car nous avons deux articles introduisant Jakarta NoSQL : un sur l'API et un autre sur ce qu'est Jakarta NoSQL et une introduction au cloud natif.


import jakarta.nosql.mapping.Column;
import jakarta.nosql.mapping.Convert;
import jakarta.nosql.mapping.Entity;
import jakarta.nosql.mapping.Id;
import java.util.Objects;

@Entity
public class Wish {
    @Id
    @Convert(ObjectIdConverter.class)
    private String id;

    @Column
    private String dream;
//getter and setter
}
public interface WishRepository extends Repository<Wish, String> {
    List<Wish> findAll();
}

L'entité et l'intégration de la base de données toutes deux réalisées, l'étape suivante est le contrôleur. JSF gère un Managed Bean qui est une classe Java Bean classique enregistrée auprès de JSF. En d'autres termes, Managed Beans est un Java Bean géré par le framework JSF. Les Managed Beans contiennent les méthodes getter et setter, la logique métier, ou même un backing bean (un bean qui contient toute les valeurs d'un formulaire HTML).


import javax.enterprise.inject.Model;
import javax.inject.Inject;
import java.util.List;

@Model
public class WishBean {
    @Inject
    private WishRepository repository;

    private String wish = "";

    public String getWish() {
        return wish;
    }

    public void setWish(String wish) {
        this.wish = wish;
    }

    public void add() {
        repository.save(Wish.of(wish));
        this.wish = "";
    }

    public List<Wish> getWishes() {
        return repository.findAll();
    }

    public void remove(String id) {
        repository.deleteById(id);
    }
}

Le bean est annoté avec "@Model" pour indiquer qu’il peut être utilisé dans la page JSF avec une portée request. Ainsi, nous allons pouvoir utiliser cette classe comme "wishBean". JSF a plusieurs portées pour ses Managed beans tels que :

  • @RequestScoped : Le bean vit aussi longtemps que la requête-réponse HTTP. Il est créé lorsqu’une requête HTTP est reçue et est détruit lorsque la réponse HTTP associée à la requête HTTP est terminée.
  • @ViewScoped : Le bean vit aussi longtemps que l'utilisateur interagit avec la même vue JSF dans la fenêtre/onglet du navigateur. Il est créé lorsqu’une requête HTTP est reçue et est détruit lorsque l'utilisateur renvoie à une vue différente.
  • @SessionScoped : Le bean vit aussi longtemps que la session HTTP. Il est créé lors de la première requête HTTP impliquant ce bean dans la session et est détruit lorsque la session HTTP est invalidée.
  • @ApplicationScoped : Le bean vit aussi longtemps que l'application web. Il est créé lors de la première requête HTTP impliquant ce bean dans l'application (ou lorsque l'application web démarre et que l'attribut eager=true est défini dans @ManagedBean) et est détruit lorsque l'application web s'arrête.

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:p="http://primefaces.org/ui">
<h:head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <title>Wish List to the new year</title>
</h:head>
<h:body>

    <h:form id="form">
        <p:panel header="Put your dreams to the next year">
            <p:panelGrid columns="2" layout="grid" cellpadding="4">
                <p:inputText id="dream" value="${wishBean.wish}" label="Wish" placeholder="Wish"/>
                <p:commandButton id="btn" action="#{wishBean.add}" update="form" icon="ui-icon-disk"/>
            </p:panelGrid>
        </p:panel>
        <p:dataTable id="table" var="wish" value="#{wishBean.wishes}">
            <p:column headerText="Wish">
                <h:outputText value="#{wish.dream}"/>
            </p:column>
            <p:column>
                <p:commandButton action="#{wishBean.remove(wish.id)}" icon="ui-icon-trash" update="form"/>
            </p:column>
        </p:dataTable>
    </h:form>
  </h:body>
</html>

La page XHTML montre à quel point il est facile d'intégrer une action avec ajax en utilisant des classes Java annotées avec des annotations JSF/CDI. Avec JSF, nous avons ajax en natif, ce qui nous permet d'utiliser l'attribut update sans trop d'efforts sur le front-end. Par exemple, pour lister des éléments, il y a #{wishBean.wishes} où est appelée la méthode getWishes dans la classe WishBean.

Définition dans Platform.sh

L'application Java est prête à fonctionner ! L'étape suivante consiste à définir les fichiers Platform.sh nécessaires à la gestion et au déploiement de l'application. Dans un premier article sur Java, nous avons défini les détails de ces trois fichiers :

  • Un routeur (.platform/routes.yaml). Platform.sh permet de définir les routes.
  • Zéro ou plusieurs conteneurs de services (.platform/services.yaml). Platform.sh vous permet de définir et de configurer entièrement la topologie et les services que vous souhaitez utiliser dans votre projet.
  • Un ou plusieurs conteneurs d'application (.platform.app.yaml). Vous contrôlez votre application et la façon dont elle sera construite et déployée sur Platform.sh via un seul fichier de configuration.

Nous allons changer le services.yaml pour ajouter MongoDB.


mongodb:
type: mongodb:3.6
disk: 512

Nous définissons le fichier pour décrire l’application.


# This file describes an application. You can have multiple applications
# in the same project.
#
# See https://docs.platform.sh/user_guide/reference/platform-app-yaml.html

# The name of this app. Must be unique within a project.
name: app

# The runtime the application uses.
type: "java:11"

disk: 1024

# The hooks executed at various points in the lifecycle of the application.
hooks:
	build:  mvn -DskipTests clean package thorntail:package

# The relationships of the application with services or other applications.
#
# The left-hand side is the name of the relationship as it will be exposed
# to the application in the PLATFORM_RELATIONSHIPS variable. The right-hand
# side is in the form `<service name>:<endpoint name>`.
relationships:
	mongodb: 'mongodb:mongodb'

# The configuration of app when it is exposed to the web.
web:
	commands:
    	start: java -jar -Xmx2048m -Dswarm.http.port=$PORT -Djava.net.preferIPv4Stack=true -Djava.net.preferIPv4Addresses=true target/wish-thorntail.jar

Déplacer le projet vers le dépôt Github

Nous allons créer un dépôt Git et un compte Platform.sh en trois étapes faciles :

  1. Créer un dépôt GitHub
  2. Créer un projet Platform.sh
  3. Intégrer Platform.sh et GitHub

Cette intégration nous permet, une fois que nous avons poussé le code à la branche master sur le dépôt Github, de générer automatiquement l'application sur Platform.sh.

Dans cet article, nous avons parlé du JSF et de la facilité avec laquelle il est possible d'intégrer des applications Java sur Jakarta EE puis de les déplacer sur GitHub. Les logiciels qui ont un CI/CD ont une grande garantie de qualité, font partie des meilleures pratiques et font de Platform.sh une solution parfaite pour votre prochain projet cloud.

 

Evaluer cet article

Pertinence
Style

Contenu Éducatif

Bonjour étranger!

Vous devez créer un compte InfoQ ou cliquez sur pour déposer des commentaires. Mais il y a bien d'autres avantages à s'enregistrer.

Tirez le meilleur d'InfoQ

Html autorisé: a,b,br,blockquote,i,li,pre,u,ul,p

Commentaires de la Communauté

Html autorisé: a,b,br,blockquote,i,li,pre,u,ul,p

Html autorisé: a,b,br,blockquote,i,li,pre,u,ul,p

BT