PROGRAMMATION ORIENTéE OBJET

LES PARADIGMES

Wikipedia :

Programming paradigms are a way to classify programming languages based on their features. Languages can be classified into multiple paradigms.

Il existe 4 paradigmes de programmation :

  • Impérative : C, Fortran
  • Orientée objet : PHP, Java, C++
  • Fonctionnelle : Lisp, Clojure
  • Pattern matching : Prolog

Il y a des langages de programmation multi paradigmes aussi comme Python, Ruby, ...

Cela se traduit souvent par la possibilité de faire des fonctions (prog. impérative), de créer des classes (prog. orienté objet) et d'utiliser des fonctions/méthodes comme map/réduce, dites immutable (prog. fonctionnelle).

Un paradigme de programmation c'est une vue de l'esprit pour l'organisation du code et cela donne aussi des principes fondamentaux du fonctionnement de ce-dernier.

L'ORIENTÉE OBJET 1/3

Wikipedia :

Object-oriented programming (OOP) is a programming paradigm based on the concept of "objects", which can contain data and code: data in the form of fields (often known as attributes or properties), and code, in the form of procedures (often known as methods).

 

L'organisation proposée par la programmation orientée objet permet de créer des classes qui sont responsables de stoquer :

  • des données, membres,
  • des fonctions pour pouvoir manipuler ces données, méthodes.

L'ORIENTÉE OBJET 2/3

Relations d'associations

Les classes sont liées entre elles soit par :

  • relation d'héritage, dite est-un,
  • relation d'appartenance, dite a-un.
  • relation de dépendance.

Exemple d'héritage : une classe mère "meuble" avec des classes filles comme "chaise", "bureau", "table", "fauteuil", etc...

Exemple d'appartenance : une classe mère "livre" avec des membres de type "auteur", "éditeur", une liste de "page", etc...

Les classes représentent les briques élémentaires, les composants, qu'on peut instancier en objet. Cette organisation devrait permettre la réutilisation de code naturellement, augmenté la lisibilité et donc la maintenabilité d'un projet.

L'ORIENTÉE OBJET 3/3

  • Classe abstract : au moins une méthode est une méthode virtual, à implémenter par les classes filles.

 

  • interface : contient uniquement des déclarations de méthodes, à implémenter par les classes qui implements l'interface.

 

  • Mot clé static : se met devant un champ ou une méthode. Permet d'utiliser un champ/une méthode sans instancié une classe.

 

  • Mot clé final : se met devant une classe, une méthode ou un champ. Sous entend l'idée que l'objet considérer est initialisé une fois et non modifiable par la suite.

Cas particuliers

JAVA - SCOPE

Les projets en Java sont organisés en package. Un package correspond à un dossier qui regroupe des classes. Les classes au sein d'un même package forme un ensemble cohérent. Exemple dans la documentation officiel du package java.util.

 

En Java il y a des mots clés qui spécifient la visibilité :

  • public : accessible par tous,
  • protected : accessible au sein d'un package,
  • private : accessible à l'intérieur d'une classe.

 

Ces mots clés se mettent devant des membres ou des méthodes d'une classe.

 

Mise en lumière avec ce projet.

JAVA - HÉRITAGE 1/2

Une classe peut hériter d'une autre. Tous les membres et méthodes de la classe parent qui sont public ou protected seront accessible dans la classe enfant. C'est le mécanisme principal pour la réutilisation de code.

La classe parent peut être une classe une classe concrète (instanciable) ou une classe abstract.

Exemple typique :

public class Polygonne {
  protected List<Vectex> sommets;
  public abstract computePerimeter();
  public abstract computeArea();
}
public class Rectangle extends Polygonne {
  public computePerimeter() {}
  public computeArea() {}
}
public class Carre extends Polygonne {
  public computePerimeter() {}
  public computeArea() {}
}

JAVA - HÉRITAGE 2/2

"Tous les carrés sont des rectangles particuliers" :

L'héritage permet de faire du polymorphisme. Par exemple, avoir une liste qui contient des objets "Polygonne", List<Polygonne>.

public class Polygonne {
  protected List<Vectex> sommets;
  public abstract computePerimeter();
  public abstract computeArea();
}
public class Rectangle extends Polygonne {
  public computePerimeter() {}
  public computeArea() {}
}
public class Carre extends Rectangle {
  public computePerimeter() {}
  public computeArea() {}
}

JAVA - Interface

Les interfaces contiennent uniquement des méthodes à implémenter :

public interface Polygonne {
  public computePerimeter();
  public computeArea();
}
public class Rectangle implements Polygonne {
  protected List<Vectex> sommets;
  public computePerimeter() {}
  public computeArea() {}
}
public class Carre extends Rectangle {
  public computePerimeter() {}
  public computeArea() {}
}

JAVA - EXERCICE 1

$ pyramide 1
*

$ pyramide 3
*****
␣***␣
␣␣*␣␣

$ pyramide 4
*******
␣*****␣
␣␣***␣␣
␣␣␣*␣␣␣

Astuce pour convertir une String en integer en Java :

L'ÉPREUVE DE LA PYRAMIDE INVERSÉE

int height = Integer.parseInt(args[0]);
$ pyramide 1
*

$ pyramide 3
*****
␣***␣
␣␣*␣␣

$ pyramide 4
*******
␣*****␣
␣␣***␣␣
␣␣␣*␣␣␣

JAVA - EXERCICE 1

$ pyramide 3 1
*****
␣***␣

$ pyramide 3 2
*****

$ pyramide 4 1
*******
␣*****␣
␣␣***␣␣

L'ÉPREUVE DE LA PYRAMIDE INVERSÉE - BONUS

JAVA - EXERCICE 2

$ anagramme basin bains
1

$ anagramme banc scan
0

$ anagramme ironique onirique
1

$ anagramme police picole
1

$ anagramme maman papa
0

JAVA - EXERCICE 3

"Tout les carrés sont des rectangles particuliers, mais tout les rectangles ne sont pas des carrés."

public class Carre extends Rectangle {
  public computePerimeter() {}
  public computeArea() {}
}
public class Rectangle {
  private Double height;
  private Double width;
  public computePerimeter() {}
  public computeArea() {}
}

JAVA - EXERCICE 3

  • Ajouter une classe Triangle pour pouvoir gérer des triangles.

 

  • Ajouter une classe abstraite Polygonne comme classe racine des autres. Dans son interface, on retrouve computePerimeter() et computeArea().

 

  • Faire une liste de Polygonne qui contient 1 Triangle, 1 Rectangle et 1 Carre. Itérer sur la liste pour appeler la méthode computeArea().

BONUS

JAVA - EXERCICE 4

  • Pouvoir instancier les 3 pokémons de base :

 - Bulbizarre

 - Salamèche

 - Carapuce

  • Pouvoir faire évoluer ces 3 pokémons respectivement en :

 - Herbizarre

 - Reptincel

 - Carabaffe

UML

Wikipedia :

The Unified Modeling Language (UML) is a general-purpose, developmental, modeling language in the field of software engineering that is intended to provide a standard way to visualize the design of a system.

 

Les diagrammes UML sont des outils de conception pour les projets informatiques. Permet de clarifier la vision sur la création d'un projet, de mettre tout le monde d'accord, et de guider les développeurs.

 

Différents exemples.

UML - classe 1/3

UML - classe 2/3

UML - Classe 3/3

Directionnalité Sémantique
in Lecture
out Écriture
inout Lecture / Écriture

UML - ENTITé

UML - Relations

Les classes sont liées entre elles par des relations :

UML - heritage 1/2

class Rectangle {
    -Double height
    -Double width
    +Rectangle(in weight : Double, in width : Double)
    +Double computePerimeter()
    +Double computeArea()
}

class Carre {
    +Carre(in sideLength : Double)
}

Rectangle <|-- Carre

UML - heritage 2/2

Commentaires :

 - En Java, une classe peut hériter que d'1 autre classe, par contre elle peut implémenter plusieurs interfaces;

 - En Java, une interface peut étendre une autre.

UML - ASsociation

Exemple :

Interprétation :

Une Personne est employée par 0 ou 1 (0..1) Entreprise.

Une Entreprise emploie 1 ou plusieurs (1..*) Personne.

Commentaires :

 - Pratique d'avoir un exemple de référence pour éviter les erreurs d'interprétation sur l'interprétation des cardinalités;

 - Durée de vie (lifetime) : 1 Personne peut exister même s'il n'y a pas d'Entreprise, par contre 1 Entreprise ne peut pas exister sans Personne;

 - Dans le code, la relation d'association se traduit par la création d'un champ pour stocker les informations liées à la relation. Ici par exemple, utiliser un Set<Personne> dans la classe Entreprise.

UML - DÉpendance

Exemple :

Interprétation :

  • La dépendance est un cas particulier de l'association;
  • Modélise le cas où une classe utilise un objet qui n'est pas stoqué dans les champs de la classe;
  • La relation de dépendance existe entre 2 classes si des changements dans 1 d'elles peut entrainer des changements dans l'autre, mais pas vice versa;
  • Dans l'exemple ci dessus, on dit que la classe Person dépend de Book.

UML - AgrÉgation

Exemple :

Interprétation :

  • L'aggrégation décrit une relation d'"appartenance";
  • Point est une part de Polygone;
  • 1 Polygonne à au moins 3 Point;
  • 1 Point appartient à aucun ou plusieurs Polygonne;
  • Les objets Polygonne et Point ont des durées de vie indépendantes.

UML - COmposition

Exemple :

Interprétation :

  • La composition est un cas particulier de l'aggrégation où les parties sont détruites quand le tout est détruit;
  • La création (copie, destruction) du composite (container) implique la création (copie, destruction) de ses composants;
  • Un composant appartient à au plus un composite.

UML - RÉalisation

Exemple :

Interprétation :

  • La réalisation représente l'implémentation d'une interface par des classes.

UML - 1 tabat l'exemple

UML - EXERCICE

Réaliser le diagramme UML de l'exercice sur les Rectangle, la version bonus, avec l'outil plantuml.

JAVA - DESIGN PATTERN

Wikipedia :

A design pattern is the re-usable form of a solution to a design problem.

 

Les design pattern sont des solutions typiques à des problèmes récurrents dans le choix du design d'un programme. On peut les voir comme des structures qui sont à adapter pour résoudre un problème de design dans le code.

 

Mon adage : "Qui connait, reconnait."

DESIGN PATTERN - FACTORY METHOD 1/2

Peut s'appliquer dans le cas où plusieurs classes implémentent les mêmes comporments dans des environnements différents.

Exemple : entreprise de transport avec poid lourd et supertanker.

Le Product déclare l'interface, qui est commune à tous les objets qui peuvent être produit par le Creator et ces sous-classes.

Le Product déclare l'interface, qui est commune à tous les objets qui peuvent être produit par le Creator et ces sous-classes.

Les Products concrets sont différentes implémentations de l'interface Product.

Les Products concrets sont différentes implémentations de l'interface Product.

La classe Creator déclare la méthode factory qui retourne les nouveau objet Product. Il est important que le type de retour de cette méthode soit l'interface des produits.

La classe Creator déclare la méthode factory qui retourne les nouveau objet Product. Il est important que le type de retour de cette méthode soit l'interface des produits.

Les Creators concrets surchargent la méthode factory de base donc ils retournent un type different de Product.

Les Creators concrets surchargent la méthode factory de base donc ils retournent un type different de Product.

DESIGN PATTERN - FACTORY METHOD 2/2

DESIGN PATTERN - Singleton 1/2

Peut s'appliquer quand vous avez besoin d'avoir accès à un objet unique à beaucoup d'endroits différents du code.

Exemple : un Logger.

La classe Singleton déclare la méthode statique getIntance qui retourne un objet du type de la classe Singleton elle même.

La classe Singleton déclare la méthode statique getIntance qui retourne un objet du type de la classe Singleton elle même.

DESIGN PATTERN - Singleton 2/2

Architecture MVC 1/2

Modèle : représente les données de l'application, définit l'interaction avec la base de données et le traitement de ces données.

Modèle : représente les données de l'application, définit l'interaction avec la base de données et le traitement de ces données.

Contrôleur : gère l'interface entre le modèle et le client, interpréte la requête de ce dernier pour lui envoyer la vue correspondante. Il effectue la synchronisation entre le modèle et les vues.

Contrôleur : gère l'interface entre le modèle et le client, interpréte la requête de ce dernier pour lui envoyer la vue correspondante. Il effectue la synchronisation entre le modèle et les vues.

Vue : représente l'interface utilisateur, n'effectue aucun traitement, elle se contente d'afficher les données que lui fournit le modèle. Il peut y avoir plusieurs vues qui présentent les données d'un même modèle.

Vue : représente l'interface utilisateur, n'effectue aucun traitement, elle se contente d'afficher les données que lui fournit le modèle. Il peut y avoir plusieurs vues qui présentent les données d'un même modèle.

Architecture MVC 2/2

JAVA - EXERCICE 5

  • Créer une liste d'entier, par exemple, qui contient des doublons. Ex.: [2, 34, 2, 42, 60]
  • Créer une fonction qui permet de retourner cette liste sans doublon.
  • Si ce n'est pas fait, utiliser la structure Set pour supprimer les doublons.
  • Version bonus : faire le même travail sur une liste d'objet "Personne" que vous aurez préalablement défini.

Java

Environnement

ECLIPSE - GIT

Faire un commit.

Faire un push.

Faire une branche.

Faire une PR.

Faire un fetch.

Mettre à jour une branche par rapport à un fetch.

 

TODO :

Vérifier comment faire un git fetch --prune : possibilité de mettre une configuration par défaut dans le git config.

ECLIPSE - Debugger

Le point sur les perspectives Eclipse.

Lancer une session de debug.

Faire des breakpoints.

Les variables, la stack trace.

L'exécution pas à pas, step into, step over.

ECLIPSE - JAVADOC

La syntaxe de Javadoc.

La génération de la documentation.

Visualiser la documentation.

Java

SPRING BOOT - Introduction

Spring Boot : un framework pour la création d'application web.

 

Spring Boot s'appuie sur le framework Spring. Les choix suivants ont été fait par Spring Boot :

  • Création d'applications Spring auto suffisante

  • Embarque Tomcat, Jetty ou Undertow directement (pas nécessaire de déployer des fichiers WAR)

  • Fournit l'utilitaire 'starter' pour simplifier le choix des dépendances et la configuration du build

  • Configuration automatique de Spring et des bibliothèques tiers lorsque c'est possible

  • Fournit des fonctionnalités prêt à l'emploi tel que les métriques, les mesures de qualités du code, et la configuration externalisée

  • Pas de génération de code et pas de nécessité d'utiliser des fichiers XML de configurations

SPRING BOOT - START

Pour commencer un nouveau projet :

Initializr

Génére un projet avec un large choix de dépendances.

SPRING BOOT - Application Context

Avec Spring Boot, la classe qui contient la méthode main() est généralement annotée par @SpringBootApplication.

 

Cette annotation est principalement responsable de rechercher les classes annotées par @Component dans le package et les sous packages de la classe principale, et d'ajouter les classes trouvées dans un container ApplicationContext.

 

Cette étape de recherche est aussi appelée "component scanning".

 

Container documentation

SPRING BOOT - BEAN

Les classes annotées par @Component sont les classes qui représentent et modèlisent la "logique métier" d'une application.

Une fois détecté par Spring Boot, ces classes deviennent des Bean et sont disponibles via l'interface ApplicationContext.

 

3 conditions pour qu'une classe puisse être un Bean :

  • 1 constructeur vide doit être disponible dans la classe
  • Chaque champ de la classe doit avoir un getter/setter
  • Implement Serializable (pas absolument nécessaire)

 

Bean documentation

 

Glossaire :

POJO : Plan Old Java Object

Demonstration APPLICATION CONTEXT

SPRING BOOT - Injection de dépendanceS

L'inversion de controle (IoC) est un principe de programmation qui découple l'instanciation des objets de leur utilisation. Cette pratique favorise la modularité du code et facilite les tests.

 

L'injection de dépendances (DI) est une façon de mettre en oeuvre l'inversion de contrôle, celle qui est utilisée par Spring Boot.
A l'initialisation Spring Boot analyse les dépendances entre les Beans qu'il a découvert lors du "component scanning". Lorsqu'un objet a besoin d'une instance d'un autre objet, Spring Boot se charge de fournir une instance de cette objet.

Le choix de l'objet à injecter s'appuie principalement sur le type de l'objet, mais ce n'est pas le seul mécanisme disponible : voir l'article sur l'injection de dépendance.

 

Glossaire :

IoC : Inversion of Control

DI : Dependency Injection

SPRING BOOT - Injection de dépendances

Demonstration Injection de Dépendances

SPRING BOOT - EXERCICE 1

Ajouter une classe GrosLoto :

 - hérite de la classe Voiture,

 - dispose d'une capacité de carburant de 80.

 

Ajouter un cas utilisant une instance de GrosLoto pour voir si le service StationService fonctionne correctement sur cette classe.

SPRING BOOT - EXERCICE 2

Ajouter à la classe Voiture les champs :

 - static final int capaciteRoue = 4

 - int roue

 

A chaque fois que la voiture roule, un roue s'âbime. Lorsque les 4 roues sont abimées, la voiture ne peut plus rouler : levé d'une exception.

 

Créer un service Garage qui permet de changerLesRoues() d'une Voiture.

 

Créer un scénario pour vérifier le fonctionne du service Garage.

Le service Garage

SPRING BOOT - QUALIFIER 1/2

Spring Boot favorise l'utilisation des interfaces grâce à l'annotation @Autowired.

 

Cela permet de changer d'implémentation simplement. Si vous avez plusieurs implémentation d'une même interface, il est nécessaire de donner un nom aux différentes implémentation : il suffit de renseigner le premier attribut de l'annotation @Component, par exemple :

@Component("complete")
public class StationService implements StationServiceInterface {
  ...
}

SPRING BOOT - QUALIFIER 2/2

Pour spécifier l'implémentation à utiliser par Spring Boot lors d'un appel à @Autowired, cela se fait grâce à l'annotation @Qualifier, par exemple :

@Autowired
@Qualifier("complete")
StationServiceInterface stationService;

Demonstration @Qualifier

SPRING BOOT - EXERCICE 3

Ajoutez une 2ième implémentation du service garage qui :

 - remplace les 4 roues,

 - fait le plein.

 

Nommez ce nouveau service "complete" et nommez le précédent service "roue".

 

Ajouter l'annotation @Qualifier pour sélection le service Garage "complete" dans le programme main.

 

Créer un scénario pour vérifier le fonctionnement de ce nouveau service Garage.

Le service Garage("complete")

SPRING BOOT - MVC 1/2

SPRING BOOT - MVC 2/2

L'organisation Model-Vue-Contrôleur est une pratique répandue pour construire des applications web.

 

Le Contrôleur est l'élément central d'un framework MVC. Il est responsable de recevoir les requêtes qui viennent du client, de faire la liaison entre les Models et les Vues, et enfin de retourner une réponse au client.

 

Le Model permet de manipuler les données (e.g. aller lire la base de donnée) et de faire des traitement.

 

La Vue permet de formatter les données fournis par un Model à un utilisateur.

Pour aller plus loin

JAVA

JSP est un langage qui permet de créer des vues avec le framework Spring/Spring Boot. C'est la partie Front-end de l'application. On désigne les fichiers JSP comme des feuilles JSP. Extension des fichiers : .jsp

 

Le rendu des feuilles JSP se fait du côté serveur.

 

Dans le projet d'exemple basic_jsp, ces fichiers sont placés dans : src/main/webapp/WEB-INF/jsp/

 

La configuration de l'emplacement des fichiers jsp se fait dans le fichier : src/main/resources/application.properties

 

Grâce aux propritétés suivante :

spring.mvc.view.prefix: /WEB-INF/jsp/
spring.mvc.view.suffix: .jsp

INTRODUCTION

La configuration des différentes routes d'une application Spring Boot se fait dans le contrôleur : une classe avec l'annotation @Controller.

 

Dans le framework Spring Boot MVC, une route correspond à :

  • une méthode du contrôleur,
  • une feuille JSP

Cette méthode publique doit être annotée avec 1 des annotations suivantes :

  • @RequestMapping
  • @GetMapping
  • @PostMapping
  • @PutMapping
  • @PatchMapping
  • @DeleteMapping

 

Les échanges de données entre le contrôleur et les vues se font via un objet model.

CONTROLEUR

L'annotation @RequestMapping est la plus générique. Elle prend en argument une chaîne de caractères qui correspond à la route à traiter :

EXEMPLE 1 - CONTROLEUR

  @RequestMapping("/")
  public String home() {
    return "home";
  }

Ici, la route est "/". La chaîne de caractères retournée, "home", correspond à une feuille JSP à retourner au client. Dans le projet d'exemple, le chemin vers cette feuille est :

src/main/webapp/WEB-INF/jsp/home.jsp

 

L'annotation @RequestMapping peut aussi prendre en argument les attributes "value" et "method" :

  @RequestMapping(value = "/", method = RequestMethod.GET)
  • value : la route à traité par la méthode

  • method : le type de requête à traité par la méthode

src/main/webapp/WEB-INF/jsp/home.jsp :

EXEMPLE 1 - JSP

<!DOCTYPE html>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html lang="en">
  <head>
    <link rel="stylesheet" type="text/css" 
          href="webjars/bootstrap/3.3.7/css/bootstrap.min.css" />
    <c:url value="/css/main.css" var="jstlCss" />
    <link href="${jstlCss}" rel="stylesheet" />
  </head>
  <body>
    <h1>Arrive a ou</h1>
    <script type="text/javascript" 
            src="webjars/bootstrap/3.3.7/js/bootstrap.min.js"/>
  </body>
</html>

Le langage JSP, c'est du code HTML enrichi.

 

Toutes les balises HTML sont accessible et utilisable.

src/main/webapp/WEB-INF/jsp/home.jsp :

EXEMPLE 1 - CSS JS GLOBAL

Il est possible d'utiliser des bibliothèques CSS et JS standard tel que bootstrap en installant la dépendance;

pom.xml :

<!DOCTYPE html>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html lang="en">
  <head>
    <link rel="stylesheet" type="text/css" 
          href="webjars/bootstrap/3.3.7/css/bootstrap.min.css" />
    <c:url value="/css/main.css" var="jstlCss" />
    <link href="${jstlCss}" rel="stylesheet" />
  </head>
  <body>
    <h1>Arrive a ou</h1>
    <script type="text/javascript" 
            src="webjars/bootstrap/3.3.7/js/bootstrap.min.js"/>
  </body>
</html>
<dependency>
    <groupId>org.webjars</groupId>
    <artifactId>bootstrap</artifactId>
    <version>3.3.7</version>
</dependency>

src/main/webapp/WEB-INF/jsp/home.jsp :

EXEMPLE 1 - CSS LOCAL

Cette exemple montre une première utilisation de la bibliothèque de balise standard (taglib) JSTL : Java server page Standard Tag Library.

 

Ici, la balise "c:url" permet d'utiliser une feuille CSS locale au projet :

src/main/resources/static/css/main.css

En utilisant la variable intermediaire "jstlCss".

<!DOCTYPE html>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html lang="en">
  <head>
    <link rel="stylesheet" type="text/css" 
          href="webjars/bootstrap/3.3.7/css/bootstrap.min.css" />
    <c:url value="/css/main.css" var="jstlCss" />
    <link href="${jstlCss}" rel="stylesheet" />
  </head>
  <body>
    <h1>Arrive a ou</h1>
    <script type="text/javascript" 
            src="webjars/bootstrap/3.3.7/js/bootstrap.min.js"/>
  </body>
</html>

src/main/webapp/WEB-INF/jsp/home.jsp :

EXEMPLE 1 - CSS LOCAL

4 bibliothèques de taglib sont développées par le projet Taglibs du groupe Apache sous le nom " Standard ".

 

Ce cours concerne uniquement la lib core.

Le langage utilisé pour la manipulation de valeurs au sein des feuilles JSP s'appelle Expression Language (EL). Des exemples seront donnés.

<!DOCTYPE html>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html lang="en">
  <head>
    <link rel="stylesheet" type="text/css" 
          href="webjars/bootstrap/3.3.7/css/bootstrap.min.css" />
    <c:url value="/css/main.css" var="jstlCss" />
    <link href="${jstlCss}" rel="stylesheet" />
  </head>
  <body>
    <h1>Arrive a ou</h1>
    <script type="text/javascript" 
            src="webjars/bootstrap/3.3.7/js/bootstrap.min.js"/>
  </body>
</html>

L'annotation @GetMapping permet de traiter les requêtes GET. Elle prend en argument une chaîne de caractères qui correspond à la route à traiter :

EXEMPLE 2 - CONTROLEUR

  @GetMapping("/greeting")
  public String greeting(
      @RequestParam(name = "name", required = false, defaultValue = "World") 
      String name,
      Model model) {
    model.addAttribute("name", name);
    return "greeting";
  }

L'annotation @RequestParam permet de récupérer un paramètre passer dans dans l'URL. Par exemple :

/greeting?name=Alice

 

Dans cet exemple, la chaîne de caractère "Alice" sera stockée dans la variable "String name", l. 4.

EXEMPLE 2 - MODEL

  @GetMapping("/greeting")
  public String greeting(
      @RequestParam(name = "name", required = false, defaultValue = "World") 
      String name,
      Model model) {
    model.addAttribute("name", name);
    return "greeting";
  }

L'échange d'information entre le contrôleur et une feuille JSP se fait via un "model", l. 5.

 

On renseigne un model comme une hashmap, avec un couple (clé, valeur), grâce à la méthode "addAttribute".

 

Le lien entre une route et une feuille JSP se fait via la valeur de retour d'une méthode. Dans cet exemple, quand le serveur est interrogé sur la route "/greeting", la feuille JSP "greeting.jsp" est retournée au client car cette méthode retourne la String "greeting".

EXEMPLE 2 - JSP

Dans la feuille JSP "greeting", on peut récupérer la valeur transmise par la model avec la syntaxe "${name}", l. 2.

src/main/webapp/WEB-INF/jsp/greeting.jsp :

<body>
  <h1>Arrive a ou ${name}</h1>
</body>

JSP permet d'utiliser les Expression Language.

JSP ET Expression LangUage

  • Expression
  • Scriptlet
  • Déclaration de fonction
  • Directive d'import
<%= expression %>
<% scriplet %>
<%! declaration de fonction java %>
<%@ directive d import %>

Vous pouvez utilisez des expressions Java directement dans une feuille JSP de la façon suivante :

EXEMPLE 3 - JSP EXPRESSION

<div>What time is it? <%=new java.util.Date()%></div>
<div>Big hello: <%=new String("Hello World").toUpperCase()%></div>
<div>25 * 4: <%=25 * 4%></div>
<div>75 < 69: <%=75 < 69%></div>

Résultat :

<div>What time is it? Fri Sep 10 16:44:16 GST 2021</div>
<div>Big hello: HELLO WORLD</div>
<div>25 * 4: 100</div>
<div>75 < 69: false</div>

Cette annotation permet d'utiliser une seule instruction Java.

Les scriplet JSP permettent d'utiliser plusieurs instruction Java dans cette balise :

EXEMPLE 4 - JSP SCRIPLET

<ul>
  <%
  List<String> gouv = Arrays.asList("Jean Castex", "Jean-Yves le Drian",
      "Barbara Pompili");
  for (String name : gouv) {
    out.println("<li>Ministre: " + name + "</li>");
  }
  %>
</ul>

Résultat :

 • Ministre: Jean Castex
 • Ministre: Jean-Yves le Drian
 • Ministre: Barbara Pompili

L'objet "out" permet de générer du code HTML depuis du code Java au sein d'une feuille JSP.

Il est aussi possible de définir des fonctions Java en JSP :

EXEMPLE 5 - JSP DECLARATION

<%!String makeItLower(String data) {
  return data.toLowerCase();
}%>
<div>
  Lower case "Hello World":
  <%=makeItLower("Hello World")%>
</div>

Résultat :

Lower case "Hello World": hello world

Il est aussi possible d'importer des fonctions Java existantes :

EXEMPLE 6 - JSP IMPORT

<%@ page import="com.example.basic.Utils"%>
<div>
  Lower case "Hello World":
  <%=Utils.makeItLower("Hello World")%>
</div>

Résultat :

Lower case "Hello World": hello world

Comme on l'a vu précédemment, il y a un objet "out" disponible en JSP, mais ce ne pas le seul :

JSP - OBJET DISPONIBLE

Comme l'objet "out", ces objet sont utilisables en JSP dans un context Java avec les syntaxes précédemment définies dans les exemples 3 à 6.

Object Classe Rôle
out javax.servlet.jsp.JspWriter Flux en sortie de la page HTML générée
request javax.servlet.http.HttpServletRequest Contient les informations de la requête
response javax.servlet.http.HttpServletResponse Contient les informations de la réponse
session javax.servlet.http.HttpSession Gère la session

Par exemple :

EXEMPLE 7 - JSP REQUEST

<div>Request user agent: <%=request.getHeader("User-Agent")%></div>

Résultat :

Request user agent: Mozilla/5.0 (X11; Linux x86_64) 
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36

Cet objet peut être utile pour avoir des informations le client qui consulte l'application (savoir si c'est un mobile ou un ordinateur par exemple), ou encore on peut inspect cette objet pour vérifier les paramètres qui sont passés dans une requête.

Par exemple :

EXEMPLE 8 - JSP RESPONSE

<%= response.setHeader("Access-Control-Allow-Credentials", "true") %>

Cet objet peut être utile pour configurer l'entête de la réponse à retourner au client par exemple.

BEAN BACKING

Lorsque vous utilisez un formulaire, il est possible de donner des contraintes sur les champs du formulaire grâce à des annotations sur les champs d'une classe qui sert de modèle au formulaire.

La liste des annotations de contraintes disponibles

 

Ce concept est appelé le Bean Backing dans le framework Spring.

POUR ALLER PLUS LOIN

Java

SPRING - Hibernate 1/2

Au sein du framework Spring, on parle de JPA/Hibernate quand on s'intéresse à la persistence de donnée, donc l'utilisation de base de donnée.

 

JPA  : Java Persistence API

 

JPA décrit les spécifications pour faire de la persistance de donnée. C'est un package qui contient principalement des interfaces.

Hibernate est l'implémentation de référence de JPA.

 

Il y a d'autre implémentation de JPA comme Eclipselink ou OpenJPA.

SPRING - Hibernate 2/2

Quel est le service rendu par JPA ?

JPA fait le lien entre les objets Java et les enregistrements en DB.
Une classe Java correspond à une Table.
Un objet Java correspond à un enregistrement dans une Table.
On parle d'ORM : Object Relationnal Mapping.

 

Hibernate fourni les requêtes : d'insertion, de mise à jour, d'effacement, et de selection.

Tout ça se fait grâce à des annotations (comme tout avec Spring).

 

JPA ENTITY

Pour qu'une classe soit associée à une table via JPA, il faut que :

  • La classe doit être un bean

Pour être un Bean :

  1. Implement Serializable
  2. Un constructeur vide dans la classe
  3. Chaque champ de la classe doit avoir un getter/setter
  • La classe doit posséder un champ qui correspond à la clé primaire de l'objet en base de donnée

Par exemple "private int id;" ou "private long id;"

  • Annotée la classe pour que JPA fasse la correspondance de cette classe avec une table, et annoté le champ qui correspond à la clé primaire

La correspondance classe <-> Table : avec l'annotation JPA "@Entity"
La déclaration du champ qui correspond à la clé primaire : avec @Id : "@Id private int id;"

Le fichier application.properties :

 - contient la configuration de JDBC

 

JDBC : Java DataBase Connectivity

Configure la connexion à la base de donnée.

 

On utilisera la base de données H2, qui est une base de donnée chargée en mémoire : pas d'écriture sur disque.

 

Est-ce que vous connaissez l'outil Postman ?

DEMONSTRATION : TUTO

CRUD et REST

CRUD est un acronyme pour décrire les opérations de base sur une base de donnée :

  • Create
  • Read
  • Update
  • Delete

 

REST : REpresentational State Transfer

Selon wikipédia, décrit une architecture logiciel concernant les requêtes entre client/serveur.

En général, quand on parle de RESTful API, c'est une API qui implémente les opérations CRUD avec différents types de requêtes :

  • GET <-> Read
  • POST <-> Create
  • PUT/PATCH <-> Update
  • DELETE <-> Delete

BATTERie de DEMONSTRATIONS

@oneToOne

@oneToMany

@manyToOne

@manyToMany

JPA ENTITY - Cycle de vie

Pour aller plus loin

Java J2EE

By Fabien ROZAR

Java J2EE

  • 73