Support Java L1 RTM
Support Java L1 RTM
PROGRAMMATION EN JAVA
L1 RTM
Objectif Général
L’objectif général de ce cours est de permettre aux apprenants d’acquérir les
compétences nécessaires pour développer des applications web robustes, évolutives
et sécurisées en utilisant java et le Framework Spring boot.
Objectifs Spécifiques
• Maitriser la syntaxe et les concepts fondamentaux de Java ;
• Maitriser la programmation orientée objet (POO) ;
• Gérer les exceptions et les erreurs ;
• Lire et écriture dans le fichier ;
• Créer les interfaces graphiques simples ;
• Comprendre l’architecture de Spring et Spring Boot ;
• Utiliser les outils modernes de développement.
Page |2
Java est utilisé pour créer différents types d'applications, allant des petites applications
embarquées aux systèmes distribués complexes.
• Vaste écosystème
Le langage bénéficie d'un grand nombre de bibliothèques (API), d'outils de
développement (JDK) et d'une communauté de développeurs active.
1. Compilation
Le code source Java est écrit par le développeur, puis compilé en un format
intermédiaire appelé bytecode.
2. Exécution
Ce bytecode est ensuite exécuté par la JVM, qui le traduit en instructions natives pour
la machine sur laquelle il s'exécute.
Exemple de code simple (programme "Hello, World!")
Page |3
Environnements Java
• JRE (Java Runtime Environment)
Il fournit les outils nécessaires pour exécuter des applications Java, y compris la JVM.
VS Code ne fournit pas le JDK, vous devez l'installer séparément ou utiliser le Coding
Pack, qui l'inclut.
• Extension Pack for Java
Installez l'Extension Pack for Java dans VS Code, qui regroupe les outils nécessaires
:
• Language Support for Java™ by Red Hat : pour le support du langage Java.
Page |4
• Maven for Java et Project Manager for Java : pour la gestion des projets
Java, y compris la génération de projets à partir d'archétypes Maven et
la gestion des dépendances, explique Visual Studio Code.
2. Configuration et Utilisation
• Démarrer un projet
Vous pouvez créer des projets Java grâce à l'extension Project Manager for Java ou
utiliser des outils comme Maven pour générer des projets existants.
• Fonctionnalités intégrées
: Une fois configuré, VS Code offre des fonctionnalités avancées telles que :
• IntelliSense : auto-complétion intelligente du code, mise en surbrillance
syntaxique et pliage de code.
• Cela rend VS Code très polyvalent, car il peut être transformé en un IDE Java
puissant en ajoutant les extensions nécessaires, tout en conservant sa légèreté
et sa rapidité.
Page |5
• Classes
• Méthodes
• Ce sont des séquences d'instructions nommées qui effectuent une tâche
spécifique.
• Commentaires
Les types de données indiquent le genre de valeur qu'une variable peut contenir. Les
principaux types sont :
• Types numériques : pour les nombres, comme les entiers (int) pour les
nombres entiers (ex: 5, -10) et les nombres flottants (float) pour les nombres à
virgule flottante (ex: 3.14, -0.5).
• Types de chaîne de caractères : pour les textes, comme "New York City".
Variables
• Une variable est un identifiant (un nom) qui représente un espace mémoire
pour stocker une donnée.
• Lors de la création d'une variable (souvent avec des mots-clés comme var), on
spécifie généralement le type de données qu'elle contiendra et on lui assigne
une valeur.
o + : addition
o - : soustraction
o * : multiplication
o / : division
• Opérateurs d'assignation : pour attribuer une valeur à une variable (ex: =).
• Opérateurs de comparaison et logiques : pour comparer des valeurs et
prendre des décisions dans un programme.
Page |7
1.2.1. Conditions(If,switch)
En Java, if et switch sont des structures conditionnelles permettant d'exécuter du
code différemment selon une condition. Le if teste des expressions booléennes
complexes et permet une logique "si ... sinon si ... sinon". Le switch est plus adapté
pour tester une seule valeur (entier, énumération, ou chaîne) contre plusieurs cas
possibles, offrant une syntaxe plus condensée et souvent plus optimisée pour de
multiples conditions exactes, contrairement au if qui est plus flexible pour des plages
de valeurs.
L'instruction if
• Quand l'utiliser : Idéal pour des conditions booléennes complexes, des tests
sur des valeurs flottantes, ou lorsqu'il y a une relation entre différentes
conditions.
L'instruction switch
• Usage : Permet de sélectionner une des nombreuses instructions à exécuter,
en fonction de la valeur d'une expression.
• Syntaxe :
Page |8
• Quand l'utiliser :
Idéal pour choisir parmi plusieurs valeurs exactes et éviter une longue chaîne de if-
else if.
• Points importants :
La boucle for
La boucle for est utilisée pour exécuter un bloc de code un nombre défini de fois. Elle
inclut généralement l'initialisation d'une variable, une condition de test et une
expression d'incrémentation ou de décrémentation.
Page |9
La boucle while
Cette boucle exécute un bloc d'instructions tant qu'une condition logique est vraie. Si
la condition est fausse au départ, le corps de la boucle ne sera jamais exécuté.
La boucle do-while
La principale différence avec la boucle while est que le bloc d'instructions est exécuté
au moins une fois avant que la condition ne soit évaluée. Le point-virgule après la
condition est une exigence de syntaxe de la boucle do-while.
1.2.3. Le tableau
En Java, un tableau est une structure de données fondamentale qui permet de stocker
un nombre fixe d'éléments du même type, accessibles par un index numérique
commençant à zéro. Pour déclarer et créer un tableau, on spécifie le type des
éléments et sa taille, puis on l'instancie avec new ou on l'initialise directement avec
P a g e | 10
des valeurs. Les tableaux possèdent une propriété length pour connaître leur taille et
sont accessibles via des boucles, notamment la boucle for.
Création et Déclaration
Pour utiliser un tableau, il faut le déclarer et l'instancier.
Les éléments d'un tableau sont accessibles par leur indice, qui commence toujours à
0.
• nomTableau[indice] permet d'accéder à un élément.
Exemple d'accès
Opérations courantes
• Obtenir la taille : La propriété length donne le nombre d'éléments du tableau.
P a g e | 11
une Voiture bleue), chacun ayant sa propre couleur et marque, et chacun pouvant
appeler la méthode demarrer().
• Elle spécifie les propriétés (attributs) et les actions (méthodes) que les objets
de ce type pourront avoir.
1.3.1. Encapsulation
L'encapsulation en Java est un mécanisme qui regroupe les données (attributs) et les
méthodes qui les manipulent au sein d'une seule classe, en cachant les détails
d'implémentation et en restreignant l'accès direct aux attributs privés via des
P a g e | 14
Exemple d'encapsulation
Prenons une classe Voiture pour illustrer ce principe :
Dans cet exemple, les variables marque et vitesse sont publiques et peuvent être
modifiées directement depuis n'importe quelle autre classe, ce qui peut mener à des
incohérences.
Pour appliquer l'encapsulation, nous rendons les attributs private et ajoutons des
méthodes public pour y accéder et les modifier :
P a g e | 15
P a g e | 16
1. Attributs private
marque et vitesse sont private. Cela signifie qu'elles ne peuvent pas être accédées ou
modifiées directement depuis une autre classe.
2. Méthodes public (Getters)
Les méthodes getMarque() et getVitesse() permettent de lire les valeurs des attributs,
mais pas de les modifier directement.
3. Méthodes public (Setters)
P a g e | 17
1. Classe fille (Sous-classe) : Création d'une classe qui étend Animal, par
exemple Chien.
P a g e | 18
Explication
• Relation "est un" : L'héritage établit une relation "est un", où un Chien est
un Animal.
Cet exemple montre comment l'héritage permet de réutiliser le code et de créer des
hiérarchies de classes, rendant le code plus organisé et maintenable.
P a g e | 20
Rôle de l'interface
• Contrat d'implémentation :
• Définit le comportement :
Elle spécifie ce qu'une classe doit faire, mais pas comment elle doit le faire.
• Supporte l'abstraction :
En ne révélant que les méthodes, elle cache les détails internes d'une fonctionnalité,
permettant une approche plus simple de la conception logicielle.
Exemple d'interface et d'abstraction
Cette interface établit le contrat que tout type de véhicule motorisé doit pouvoir faire
le plein.
2. Transfert du contrôle
Le flux d'exécution du programme est interrompu et le contrôle est transféré à un «
gestionnaire d'exception » (handler) approprié.
3. Propriété de la pile d'appels
Si le bloc de code actuel ne gère pas l'exception, celle-ci est propagée à la méthode
appelante, et ainsi de suite à travers la pile d'appels jusqu'à être traitée ou que le
programme s'arrête.
Mots-clés et structures
• try
: Le bloc try est utilisé pour encadrer le code susceptible de lancer une exception.
• catch
: Le bloc catch est exécuté si une exception du type spécifié (ou un de ses sous-types)
est levée dans le bloc try.
• finally
: Le bloc finally est un bloc de code qui sera toujours exécuté, qu'une exception soit
levée ou non. Il est souvent utilisé pour libérer des ressources (comme fermer des
fichiers).
• throw
: Le mot-clé throw est utilisé pour générer explicitement une exception à partir d'un
objet.
• throws
P a g e | 24
Dans la signature d'une méthode, throws indique que la méthode peut potentiellement
lever des exceptions de certains types, signalant ainsi à l'appelant qu'il doit les gérer.
Types d'exceptions
• Error
• Exception
Représente des problèmes moins graves, souvent récupérables, tels
que ArithmeticException (division par zéro), NullPointerException,
ou FileNotFoundException.
• RuntimeException
Une classe d'exceptions qui ne sont pas obligatoires à intercepter avec un bloc try-
catch.
En Java, la gestion des exceptions permet d'intercepter et de traiter les erreurs lors
de l'exécution d'un programme en utilisant les mots-clés try, catch, et finally. Un
bloc try contient le code qui pourrait générer une erreur, tandis que le bloc catch traite
l'exception si elle se produit. Le bloc finally, toujours exécuté, est utilisé pour le
nettoyage des ressources. Pour lever une exception, on utilise throw,
et throws indique qu'une méthode peut en propager une.
Mécanisme de gestion des exceptions
1. Levée de l'exception
Lorsqu'une erreur survient (par exemple, division par zéro), un objet d'exception est
créé et « levé ».
2. Transfert du contrôle
Mots-clés et structures
• try
Le bloc try est utilisé pour encadrer le code susceptible de lancer une exception.
P a g e | 25
• catch
Le bloc catch est exécuté si une exception du type spécifié (ou un de ses sous-types)
est levée dans le bloc try.
• finally
Le bloc finally est un bloc de code qui sera toujours exécuté, qu'une exception soit
levée ou non. Il est souvent utilisé pour libérer des ressources (comme fermer des
fichiers).
• throw
Le mot-clé throw est utilisé pour générer explicitement une exception à partir d'un
objet.
• throws
Dans la signature d'une méthode, throws indique que la méthode peut potentiellement
lever des exceptions de certains types, signalant ainsi à l'appelant qu'il doit les gérer.
Types d'exceptions
• Error
1. List (Liste)
• Description : Une collection ordonnée qui peut contenir des éléments
dupliqués. L'ordre des éléments est préservé, et on peut y accéder par un
index.
P a g e | 26
• Utilisation : Idéale lorsque l'ordre des éléments est important, comme dans
l'affichage d'une liste d'éléments dans une interface utilisateur ou pour des
algorithmes nécessitant une séquence.
2. Set (Ensemble)
• Description : Une collection qui ne permet pas les doublons. Les éléments ne
sont pas nécessairement ordonnés.
• Utilisation : Parfait pour stocker des données uniques, comme une liste
d'adresses e-mail pour éviter les doublons, ou pour des opérations qui
nécessitent des éléments uniques.
• Implémentation courante : HashSet.
• Exemple :
P a g e | 27
3. Map (Carte)
En Java, une Map est une structure de données qui stocke des éléments sous forme
de paires clé-valeur, où chaque clé est unique et permet de retrouver une valeur
associée. Elle fait partie du framework Java Collections et est implémentée par des
classes comme HashMap. Pour l'utiliser, vous instanciez une classe Map (par
exemple, new HashMap<>()), ajoutez des paires avec put(clé, valeur), puis récupérez
des valeurs avec get(clé).
: La Map stocke des données sous forme de paires où chaque valeur est associée à
une clé unique.
• Clés uniques
: Il ne peut y avoir qu'une seule instance de chaque clé dans une Map.
• Valeurs répétées
: Les valeurs ne sont pas obligées d'être uniques et peuvent apparaître plusieurs fois.
• Interface de collection
: La Map est une interface du framework [Link] qui n'est pas un sous-type de
l'interface Collection.
P a g e | 28
Exemple d'utilisation
Voici un exemple simple pour créer une Map de noms d'étudiants et leur âge, et pour
y accéder :
Exemple :
1.4.3. Generics
Les génériques Java sont un mécanisme permettant de définir des classes, des
interfaces et des méthodes qui peuvent fonctionner avec différents types de données,
P a g e | 29
• Lisibilité du code
: Le code est plus clair car les types sont explicitement définis.
• Flexibilité
: Vous pouvez écrire des classes ou des méthodes réutilisables pour différents types
de données sans avoir à les dupliquer.
• Réduction des conversions
: Vous n'avez plus besoin de convertir manuellement les types (comme caster
des Object en String ou Integer).
Comment ça marche ?
• Paramètres de type
: Ce sont des symboles, souvent des lettres comme T, qui servent de placeholders
pour les types.
• Types paramétrés
: Une fois le type précisé avec l'opérateur diamant, le type générique devient un type
paramétré, comme ArrayList<String>.
• Effacement de type (Type Erasure)
: Pendant la compilation, les informations sur les génériques sont supprimées pour
garantir la rétrocompatibilité avec les anciennes versions de Java. Cela signifie que
l'information sur le type n'est pas disponible à l'exécution.
Exemple
P a g e | 30
• Explication :
o File file = new File("[Link]"); crée un objet File représentant le
fichier à lire.
o Scanner scanner = new Scanner(file); initialise un objet Scanner pour
lire à partir de ce fichier.
o while ([Link]()) { ... } est une boucle qui continue tant qu'il
y a des lignes à lire dans le fichier.
• Explication :
o FileWriter writer = new FileWriter("[Link]"); crée un
objet FileWriter. Si [Link] existe, son contenu sera remplacé.
Bonnes pratiques
Les opérations de fichier peuvent échouer, il est donc essentiel de les entourer de
blocs try-catch pour gérer les exceptions
comme FileNotFoundException ou IOException.
P a g e | 33
• Conteneur léger
: Le cœur de Spring est un conteneur qui gère les "Beans" (objets) et leurs relations,
instanciant les objets nécessaires et les rendant disponibles à l'application.
• Modularité
: Les développeurs peuvent choisir les modules Spring dont ils ont besoin, comme
Spring Security pour la sécurité ou Spring Data pour l'accès aux données, ce qui offre
une grande flexibilité.
• Simplification
: Spring automatise de nombreuses tâches répétitives, comme la gestion des bases
de données ou la sécurité, et simplifie la création d'applications complexes.
• Développement simplifié
: Spring réduit la complexité de la création d'applications Java.
• Flexibilité et modularité
: Il permet aux développeurs de n'utiliser que les composants dont ils ont besoin.
2. Configuration
: Le conteneur est configuré via des fichiers XML, des classes Java annotées
avec @Configuration et @Bean, ou en utilisant le composant scanning
avec @ComponentScan.
3. Injection de Dépendances (DI)
: Une fois la configuration lue, le conteneur crée les instances des classes (beans) et
injecte automatiquement les dépendances nécessaires.
• Meilleure modularité
P a g e | 35
: Le code est plus faiblement couplé, ce qui le rend plus facile à maintenir et à faire
évoluer.
• Dépendances :
Une classe a besoin d'une référence à une autre classe (ou une interface) pour
fonctionner.
• Injection :
• Avantages :
• Couplage faible : La classe n'est plus liée à l'implémentation concrète
de sa dépendance.
• Tests facilités : Il est possible d'injecter des objets mocks pour les tests
unitaires.
2. Lancez l'application:
Explication du fonctionnement
• Développement accéléré
P a g e | 38
• Applications autonomes
Vous pouvez construire des applications qui s'exécutent immédiatement avec un
serveur web intégré, sans avoir besoin de dépendances externes.
• Configuration automatique
Fonctionnalités clés
• Configuration automatique
Les configurations sont déduites des dépendances ajoutées au projet.
• Annotations
Utilise des annotations comme @SpringBootApplication pour configurer et démarrer
l'application de manière concise.
Des serveurs comme Tomcat peuvent être intégrés directement dans l'application,
évitant le besoin d'un serveur externe.
• Projets prêts à l'emploi
Vous pouvez utiliser le service en ligne Spring Initializr pour générer un modèle de
projet avec les dépendances nécessaires.
2.2.1. Spring Initializr
Spring Initializr est un outil web qui permet de créer rapidement le squelette d'un projet
Spring Boot. Il génère la structure de base de l'application, sélectionne le langage
(Java, Kotlin, Groovy), l'outil de build (Maven ou Gradle), et permet d'ajouter des
dépendances sous forme de « starters » (des ensembles de bibliothèques) pour les
besoins de l'application, comme le web ou l'accès aux bases de données.
Comment ça marche ?
P a g e | 39
1. Accéder à l'outil
Vous vous rendez sur l'interface web de Spring Initializr, généralement accessible
via [Link].
2. Configurer le projet
Vous spécifiez les détails de votre projet, tels que le langage, le type de projet (Maven
ou Gradle), la version de Spring Boot, et les métadonnées du projet (nom du groupe,
nom de l'artefact).
4. Générer le projet
Une fois configuré, l'outil génère un fichier ZIP contenant la structure du projet, les
fichiers de configuration ([Link] pour Maven, [Link] pour Gradle) et les
dépendances sélectionnées.
Avantages
• Gain de temps
Il fournit une interface conviviale pour configurer les éléments nécessaires à une
application.
• Flexibilité
Vous pouvez choisir parmi différentes options de langage, d'outils de build et de
dépendances.
• Intégration
• src/main/java
• src/test
: Contient les tests unitaires et d'intégration de l'application.
2. Générer le projet
Remplissez les métadonnées du projet et cliquez sur "Generate". Téléchargez le
fichier ZIP.
3. Décompresser et ouvrir
: Décompressez le fichier et ouvrez le projet dans votre IDE (comme IntelliJ IDEA).
P a g e | 41
Pour récupérer des données d'une requête HTTP, vous pouvez utiliser des
annotations sur les méthodes de vos contrôleurs :
• @PathVariable : Capture des variables d'URL, par exemple /utilisateurs/{id}.
Spring Boot examine le classpath et les dépendances de votre projet pour identifier
les bibliothèques installées (comme celles des "starters").
2. Conditions d'application :
Pour chaque dépendance détectée, Spring Boot vérifie si des conditions spécifiques
sont remplies en utilisant des annotations conditionnelles (par
exemple, @ConditionalOnClass, @ConditionalOnBean).
Si les conditions sont réunies, Spring Boot configure automatiquement les beans et
les composants Spring nécessaires, comme un DataSource pour une base de
données ou un serveur web embarqué (Tomcat par défaut).
Comment activer l'autoconfiguration :
Si vous préférez, vous pouvez utiliser cette annotation directement sur une de vos
classes @Configuration pour activer spécifiquement la configuration automatique.
Avantages de l'autoconfiguration :
• Développement accéléré :
Contexte
Les fichiers [Link] et [Link] servent à définir des paramètres
pour votre application Spring Boot. Le cadre Spring Boot charge automatiquement ces
fichiers à partir du répertoire src/main/resources.
Différences entre [Link] et [Link]
• [Link]
Un format simple de paires clé-valeur, idéal pour des configurations courtes et
simples.
• [Link]
Un format basé sur l'indentation (YAML) qui est plus lisible et structuré,
particulièrement adapté aux configurations complexes avec des propriétés
imbriquées.
P a g e | 43
Exemples de configuration
[Link]
2.2.3. Entité
Pour créer une entité Java en utilisant JPA (Java Persistence API), vous créez une
classe Java classique, y ajoutez l'annotation @Entity au niveau de la classe pour
indiquer qu'elle représente une table de base de données, puis vous définissez les
champs de la classe qui correspondent aux colonnes de la table, en utilisant @Id pour
P a g e | 44
la clé primaire et @Column pour les autres champs. Des constructeurs, des getters et
des setters sont également requis pour la classe d'entité.
2.2.4. Repository
Pour créer un « repository » en Java, notamment avec le framework Spring Data
JPA, vous devez créer une interface Java qui étend une interface de Spring Data
comme JpaRepository ou CrudRepository. Cette interface définit les opérations de
base de données (CRUD), et Spring s'occupe de l'implémentation, vous offrant des
méthodes pour interagir avec votre base de données sans écrire de code d'accès aux
données manuel. Vous pouvez ensuite utiliser l'annotation @Repository sur des
classes spécifiques si vous avez besoin d'une logique personnalisée, ou vous fier à
l'implémentation automatique de Spring.
Voici les étapes détaillées pour créer un repository en utilisant Spring Data JPA :
1. Créez une classe d'entité
P a g e | 48
Cette classe représente votre objet de données (par exemple, Produit) et est
généralement annotée avec @Entity pour indiquer qu'elle est mappée à une table de
base de données.
: Spring Data JPA fournit automatiquement des méthodes pour les opérations CRUD
(Create, Read, Update, Delete).
• Personnalisation facile
2.2.5. Contrôleur
Pour créer un contrôleur dans Java avec Spring, créez une classe Java et ajoutez-y
l'annotation @Controller ou @RestController. Utilisez ensuite
P a g e | 49
l'annotation @RequestMapping sur les méthodes pour ** mapper les URL spécifiques
aux méthodes** qui traiteront les requêtes HTTP. L'annotation @Controller est utilisée
pour les applications MVC où le contrôleur renvoie des vues (fichiers HTML), tandis
que @RestController est utilisée pour créer des API REST qui renvoient directement
des données (souvent au format JSON).
• Allez sur le site Spring Initializr et configurez votre projet avec les
dépendances nécessaires, comme "Spring Web".
• Téléchargez et importez le projet dans votre IDE (comme IntelliJ IDEA
ou Eclipse).
o Utilisez
l'annotation @RequestMapping, @GetMapping, @PostMapping, etc.,
pour spécifier le chemin de l'URL et la méthode HTTP que la méthode
doit gérer.
P a g e | 51
1. Exécutez et testez :
2.2.5. DTO
Pour créer un DTO (Data Transfer Object) en Java avec Spring Boot, vous définissez
une classe (ou un Java Record) qui contient uniquement les champs nécessaires à
l'exportation des données, puis vous mappez vos objets d'entité vers ce DTO, souvent
à l'aide d'une bibliothèque comme MapStruct ou manuellement via la couche
service. Ce processus permet de contrôler les données exposées, d'améliorer la
sécurité, et de découpler les couches de l'application pour plus de maintenabilité et
de flexibilité.
Voici les étapes pour créer et utiliser des DTOs en Spring Boot :
Étapes détaillées :
• Assurez-vous que le Java Development Kit (JDK) est installé sur votre
système. Vous pouvez vérifier avec la commande java -version dans
votre terminal.
• Recherchez et installez :
5. Lancer l'application
• Vous pouvez maintenant commencer à développer votre application
Spring Boot. Pour exécuter l'application, utilisez l'icône ou la commande
appropriée, souvent le tableau de bord Spring Boot ou une option « Run
Java » dans VS Code.
P a g e | 53
4. Code Sources
• Entité Client
• package [Link];
• import [Link];
• import [Link].*;
• import lombok.*;
•
• @Entity
• @Table(name = "clients")
• @Getter
• @Setter
• @ToString
• public class Client {
•
• @Id @GeneratedValue(strategy = [Link])
• private int id;
•
• private String firstName;
• private String lastName;
•
• @Column(nullable = false, unique = true)
• private String email;
•
• private String phone;
•
• private String adresse;
• private String status;
• private Date createdAt;
•
• }
•
P a g e | 56
• Client DTO
• package [Link];
•
• import [Link].*;
• import [Link];
• import [Link];
•
• @Getter
• @Setter
• public class ClientDto {
•
• @NotEmpty(message = "The First Nme is required")
• private String firstName;
•
• @NotEmpty(message ="The last name is required")
• private String lastName;
•
• @NotEmpty(message ="The email name is required")
• @Email
• private String email;
•
• private String phone;
• private String adresse;
•
• @NotEmpty(message ="The last name is required")
• private String status;
•
• }
•
• Client Repository
• package [Link];
•
• import [Link];
•
• import [Link];
•
• Client Contrôleur
P a g e | 57
• package [Link];
•
• import [Link];
•
• import [Link];
• import [Link];
• import [Link];
• import [Link];
• import [Link];
• import [Link];
• import [Link];
•
• import [Link];
• import [Link];
• import [Link];
•
• import [Link];
•
• import [Link].*;
•
• @Controller
• @RequestMapping("/clients")
• public class ClientController {
•
• @Autowired
• private ClientRepository clientRepository;
•
• @GetMapping({"","/"})
• public String getClients(Model model) {
• var clients =[Link]([Link]([Link],"id"));
• [Link]("clients", clients);
• return "clients/index";
• }
•
• @GetMapping("/create")
• public String createClient(Model model){
• ClientDto clientDto = new ClientDto();
•
• [Link]("clientDto", clientDto);
•
• return "clients/create";
• }
•
• @PostMapping("/create")
• public String createClient(
• @Valid @ModelAttribute ClientDto clientDto,
P a g e | 58
• BindingResult result
• ){
•
• if([Link]([Link]()) != null){
• [Link](new FieldError("clientDto","email",
[Link](),
• false, null,null, "Email adresse is already used")
• );
• }
•
• if([Link]()){
• return "clients/create";
• }
•
• Client client = new Client();
•
• [Link]([Link]());
• [Link]([Link]());
• [Link]([Link]());
• [Link]([Link]());
• [Link]([Link]());
• [Link]([Link]());
• [Link](new Date());
•
• [Link](client);
•
• return "redirect:/clients";
• }
•
• @GetMapping("/edit")
• public String editClient(Model model,@RequestParam int id){
• Client client = [Link](id).orElse(null);
•
• if(client == null) {
• return "redirect:/clients";
• }
•
• ClientDto clientDto = new ClientDto();
•
• [Link]([Link]());
• [Link]([Link]());
• [Link]([Link]());
• [Link]([Link]());
• [Link]([Link]());
• [Link]([Link]());
•
• [Link]("client", client);
P a g e | 59
• [Link]("clientDto", clientDto);
•
• return "clients/edit";
•
• }
•
• @PostMapping("/edit")
• public String editClient(
• Model model,
• @RequestParam int id,
• @Valid @ModelAttribute ClientDto clientDto,
• BindingResult result
• ){
•
• Client client = [Link](id).orElse(null);
•
• if(client == null) {
• return "redirect:/clients";
• }
•
• [Link]("client", client);
•
• if([Link]()){
• return "clients/create";
• }
•
• //update
•
• [Link]([Link]());
• [Link]([Link]());
• [Link]([Link]());
• [Link]([Link]());
• [Link]([Link]());
• [Link]([Link]());
•
• try{
• [Link](client);
•
• }catch(Exception e){
•
• [Link](
• new FieldError("clientDto","email", [Link]()
• ,false,null,null,"Email Adresse is already used")
• );
•
• return "client/edit";
•
P a g e | 60
• }
• return "redirect:/clients";
• }
•
• @GetMapping("/delete")
• public String deleteClient(@RequestParam int id){
• Client client = [Link](id).orElse(null);
•
• if(client != null) {
• [Link](client);
• }
•
• return "redirect:/clients";
• }
•
• }
•
• Home Contrôleur
• package [Link];
•
• import [Link];
• import [Link];
•
• @Controller
• public class HomeController {
•
• @GetMapping("/")
• public String home() {
• return "home/index"; // Renvoie le nom de la vue ([Link])
• }
•
• }
•
• </div>
•
• <div class="row mb-3">
• <label class="col-sm-4 col-form-label">Adresse</label>
• <div class="col-sm-8">
• <input class="form-control" th:field="${[Link]}"/>
• <p th:if="${#[Link]('adresse')}"
• th:errorclass="text-danger"
• th:errors="${[Link]}"></p>
•
• </div>
• </div>
•
• <div class="row mb-3">
• <label class="col-sm-4 col-form-label">Status</label>
• <div class="col-sm-8">
• <select class="form-control" th:field="${[Link]}">
•
• <option value='New'>New</option>
• <option value='Permanent'>Permanent</option>
• <option value='Lead'>Lead</option>
• <option value='Occasional'>Occasional</option>
•
• <option value='nactiv'>Inactive</option>
• </select>
•
• <p th:if="${#[Link]('status')}"
• th:errorclass="text-danger"
• th:errors="${[Link] }"></p>
• </div>
• </div>
•
• <div class="row">
• <div class="offset-sm-4 col-sm-4 d-grid">
• <button type="submit" class="btn btn-primary">Save</button>
• </div>
•
• <div class="col-sm-4 d-grid">
• <a class="btn btn-outline-primary"
href="/clients">Cancel</button>
• </div>
•
• </div>
•
• </form>
•
• </div>
P a g e | 63
•
• </div>
•
• <script rel="stylesheet"
th:src="@{/bootstrap/js/[Link]}"></script>
• </body>
• </html>
P a g e | 64
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Client Manager</title>
<link rel="stylesheet" th:href="@{/bootstrap/css/[Link]}">
</head>
<body>
</div>
</div>
<option value='New'>New</option>
<option value='Permanent'>Permanent</option>
<option value='Lead'>Lead</option>
<option value='Occasional'>Occasional</option>
P a g e | 66
<option value='nactiv'>Inactive</option>
</select>
<p th:if="${#[Link]('status')}"
th:errorclass="text-danger"
th:errors="${[Link] }"></p>
</div>
</div>
<div class="row mb-3">
<label class="col-sm-4 col-form-label">Created at</label>
<div class="col-sm-8">
<input class="form-control-plaintext" readonly
th:value="${[Link]}"/>
</div>
</div>
<div class="row">
<div class="offset-sm-4 col-sm-4 d-grid">
<button type="submit" class="btn btn-primary">Save</button>
</div>
<div class="col-sm-4 d-grid">
<a class="btn btn-ouline-primary" href="/clients">Cancel</button>
</div>
</div>
</form>
</div>
</div>
<script rel="stylesheet"
th:src="@{/bootstrap/js/[Link]}"></script>
</body>
</html>
P a g e | 67
• Tableau Client
• <!doctype html>
• <html lang="en" xmlns:th="[Link]
• <head>
• <meta charset="utf-8">
• <meta name="viewport" content="width=device-width, initial-scale=1">
• <title>Client Manager</title>
• <link rel="stylesheet" th:href="@{/bootstrap/css/[Link]}">
• </head>
• <body>
•
• <div class="container my-3">
• <h1 class="text-center mb-3">Liste des clients</h1>
• <a class="btn btn-primary" href="/clients/create">Nouveau Client</a>
•
• <table class="table">
• <thead>
• <tr>
• <th>ID</th>
• <th>Name</th>
• <th>Email</th>
• <th>Phone</th>
• <th>Adresse</th>
• <th>Status</th>
• <th>Created At</th>
• <th>Actions</th>
• </tr>
• </thead>
• <tbody class="table-group-divider">
• <tr th:each="client: ${clients}">
• <td th:text="${[Link]}"></td>
• <td th:text="${[Link]} +' '+ ${[Link]}"></td>
• <td th:text="${[Link]}"></td>
• <td th:text="${[Link]}"></td>
• <td th:text="${[Link]}"></td>
• <td th:text="${[Link]}"></td>
• <td th:text="${[Link]().substring(0,10)}"></td>
• <td style="white-space:nowrap">
• <a class="btn btn-primary btn-sm"
th:href="@{/clients/edit(id=${[Link]})}">
• Edit
• </a>
•
• <a class="btn btn-danger btn-sm"
th:href="@{/clients/delete(id=${[Link]})}"
• onclick ="return confirm('are you sure?')">
• Delete
P a g e | 68
• </a>
•
• </td>
•
• </tr>
• </tbody>
• </table>
•
• </div>
•
• <script rel="stylesheet"
th:src="@{/bootstrap/js/[Link]}"></script>
• </body>
• </html>
[Link]=jdbc:mysql://localhost:3306/db6
[Link]=root
[Link]=
[Link]-class-name=[Link]
[Link]-platform=[Link].MySQL8Dialect
[Link]-auto=update
[Link]-sql= true
P a g e | 69
2.2.3. Entité.............................................................................................................43
2.2.4. Repository ..................................................................................................47
2.2.5. DTO ...............................................................................................................51
2.3. Création projet avec VS CODE ........................................................................51
2.6. Cas Pratique avec une application Spring Boot .........................................53