mercredi 3 août 2005

Designing the User Interface




Ce livre aborde la création d'interface graphique de façon très complète. Plusieurs facteurs doivent être pris en compte afin de créer une interface graphique: public visé, expérience, domaine relié, matériel utilisé...

Beaucoup de livre existe sur la programmation, mais sur la conception d'interface graphique, il en existe beaucoup moins, alors que cette partie devient de plus en plus importante.

Un historique ainsi que des concepts plus novateurs encore très peu répandus y sont discutés. L'auteur aborde l'aspect physiologique de l'être l'humain et l'impact engendré sur la création d'interface. Plusieurs exemples sur de bonne interface et de mauvaise interface sont présenté.

On y traite de divers concepts afin de diminuer les temps d'apprentissage de l'usager. Beaucoup d'exemples concrets y sont traités.

En bref, les concepts clé y sont traités: uan, klm, sémaphore, gestion, le matériel, la documentation... C'est un livre assez avancé qui s'adresse aux gens désirant de mieux comprendre cette facette du développement logiciel.

mercredi 6 juillet 2005

Interface utilisateur


INTERFACE UTILISATEUR

Design d'interface usager

Vous avez sûrement remarqué que certains logiciels étaient plus faciles d'utilisation que d'autres. Le logiciel a tellement bien été conçu que tout semble nous paraître très logique même si c'est la première fois qu'on utilise. Un tel facteur peut contribuer à augmenter ou à diminuer l'adoption d'un logiciel par des usagers. Lorsque interface est bien réussi, elle devient transparente pour l'usager et ce dernier peut se concentrer totalement sur le travail qu'il doit effectuer.

Public visé

Lors de la création d'une interface, faut tenir compte du public qu'on vise avec le logiciel créé. On doit regarder à qui s'adresse ce logiciel. Imaginons qu'on doive créer un logiciel de création dessins. On a deux groupes d'individus.
  • Un groupe d'enfants de 10ans
  • Un groupe de graphistes
L'interface du logiciel pour le premier groupe devra être très simple et intuitive. Pour le second groupe, on sait qu'ils ont déjà une bonne connaissance du dessin et qu'il maîtrise leur domaine.

Facteur humain à mesurer

Ces facteurs doivent être considérés lors de la création d'une interface usagée. Il n'est pas nécessaire d'exceller dans chaque domaine. Il est possible de faire des compromis : on fait les tâches demandées plus lentement, mais on fait beaucoup moins d'erreurs.

Temps d'apprentissage

C'est le temps nécessaire à l'usager à apprendre à utiliser les commandes pour exécuter une tâche donnée.

Vitesse d'exécution des tâches

C'est le temps pris par l'usager à remplir une tâche donnée.

Erreur

C'est le nombre, la sorte d'erreur et le temps mis par l'usager à corriger son erreur.

Mémorisation

C'est la capacité de l'usager à se rappeler comment utiliser le logiciel, faire les tâches spécifiées lorsqu'il utilise peu ou presque pas le logiciel.

Satisfaction

C'est le niveau de satisfaction de l'usager par rapport au logiciel.

Diversité humaine

De nombreux facteurs entrent en ligne de compte pour créer une interface : habilité physique, habilité cognitive, différence culturelle et culturelle.

Habilité physique

L'âge des personnes, son sexe, ses dimensions, handicap ... influencent la capacité des gens à utiliser un logiciel. Tous ces critères font en sorte que la création d'un usager moyen soit complexe. Il y a aussi l'environnement où le logiciel sera utilisé : intensité de la lumière, clavier utilisé, hauteur de la chaise...

Habilité cognitive

La capacité cognitive est la base de la résolution des problèmes, tant sur le plan de la prévention que sur celui de la réaction et de l'élaboration de stratégies à court, moyen et long termes. Quelques facteurs tels que le temps de perception, mémoire à court et moyen, terme, apprentissage, prise de décision... font partie des catégories des processus cognitifs humains. La drogue, fatigue ... viennent affecter ces éléments.

Différence culturelle et personnelle

La perception n'est pas identique pour tout le monde. On a qu'à penser à comment les hommes et les femmes voient le sexe. ;) Il y aussi la diversité culturelle. Pour une culture donnée, les couleurs n'ont pas le même sens, de plus le format de la date et de l'heure, les mesures... ne sont pas les mêmes.

Lorsqu'on fait une interface, il faut regarder lequel de ces points s'applique et ensuite on doit les gérer de façon très efficace. Imaginer un peu la création d'une interface pour un logiciel qui serait utilisé à travers le monde.

Règle de design d'interface


Consistance

La consistance est importante pour ne pas mélanger un usager. La consistance devrait être présente dans les actions que l'usager doit faire, les menus (nom), les couleurs, police de caractère. Par exemple, si vous employez une police de caractère de 12 de type Arial dans un formulaire, utiliser là dans vos autres formulaires. Il sera certainement plus aisé d'effectuer une lecture par la suite.

Raccourci

Il peut être intéressant pour un néophyte d'utiliser la souris, mais beaucoup d'utilisateurs expérimentés préfèrent utiliser le clavier pour exécuter leur tâche plus rapidement. Ainsi, les utilisateurs expérimentés ne se sentent pas lésés. La durée de vie de l'interface pourra ainsi être augmentée, après quelque temps l'utilisateur débutant pourra commencer à utiliser ces raccourcis et profitez de ses avantages. Les raccourcis sont très utiles dans les menus, ils permettent d'exécuter des tâches plus rapidement. Une autre possibilité intéressante est les macros. Les macros permettent de faire plusieurs actions en appuyant sur une combinaison de touche. On peut imaginer pour un traitement de texte, une macro qui permettrait d'aligner le texte à gauche, de mettre le texte à double interligne et de mettre le texte en noir en appuyant par exemple surt ctrl 8.

Feed-back

À chaque action de l'usager, il devrait y avoir un message d'information pour l'usager concernant le système. Le message retourné peut être minime pour des actions fréquentes, mais devrait être plus significatif pour celles qui sont très importantes ou inutilisées. Un bon exemple est la suppression d'un fichier dans Windows, lorsque efface un fichier à l'aide du clavier, un message nous demande confirmation. L'usager s'est ainsi qu'il supprimera ce fichier s'il accepte. Un autre exemple est la gravure de CD, lorsqu'on grave un CD, il y a toujours un message du temps qu'il reste avant que la gravure se termine.

Gestion d'erreur

L'interface devrait faire en sorte que le risque d'erreur soit le plus bas possible. Ne pas permettre d'entrer de caractère alphabétique dans un champ numérique. Lorsqu'il y a une ou des erreurs, l'usager ne devrait pas avoir besoin de rentrer à nouveau toutes les informations, uniquement celles fautives devraient être entrées à nouveau. À ce niveau, plusieurs sites web, mettre une «*» à côté des champs fautifs lors d'une saisie de donnée. Les messages devraient être le plus significatifs possible. «Erreur -201» ne signifie pas grand chose pour un usager.

Retour en arrière

Il devrait être possible de revenir en arrière lorsqu'une action est exécutée. Les usagers sont moins inquiets ainsi. Ils sont plus enclins à essayer davantage d'options.

Réduction de l'utilisation de la mémoire à court terme

La mémoire à court terme est très limitée. Tout devrait être mis en oeuvre pour utiliser le moins possible l'utilisation de cette mémoire. Des cours sur la façon d'utiliser le logiciel sont un bon moyen d'utiliser la mémoire à long terme au lieu du court terme.

Composant

Il y a quelques règles concernant les données pour les composants. Il n'est pas rare de voir autant d'options dans un logiciel. Il arrive trop souvent qu'il y en a trop.


Il faut de plus que ces options et un lien entre elles. Il est beaucoup plus rapide d'effectuer une recherche lorsque les données sont groupées. Il était facile pour cet exemple de regrouper les éléments. Il devrait y avoir un lien solide entre les éléments.


Il est peut-être long et complexe à trouver un lien entre les diverses options qu'on veut inclure, mais en les regroupement, l'usager trouve plus rapidement ce qu'il désire et sera moins confu.
ComposantMax d'élément à afficher
Bouton radio6
Case à cocher6
Liste de sélection12
Liste de visualisationPlus de 12

Séquence de présensation

Il est possible de présenter les données de diverses façons: chronologique, ordre numérique, propriétés, les plus utilisées, de façon aléatoire... L'ordre alphabétique est l'une des façons les plus performantes. Ci-dessus, on a distingué les données par des catégories: transports, chambre. C'est déjà beaucoup mieux que la première façon. Il aurait été encore plus efficace si on aurait mis les données en ordre alphabétiques dans chaque catégorie. Le temps de recherche aurait diminué.

jeudi 16 juin 2005

Guide utilisateur


GUIDE UTILISATEUR

Imaginez si vous auriez à apprendre linux ou oracle sans guide à l'usager. Vous sauriez sûrement décourager et vous auriez bien raison. Pour diverse raisons, nous sommes amenés à apprendre un nouveau logiciel. Souvent, il n'y a aucune documentation disponible pour nous aider à comprendre le logiciel. Il est alors beaucoup plus long à maîtriser un tel outil lors de cette situation. Lorsque vous développez un logiciel qui sera utilisé par plusieurs personnes, il est important de prévoir un document qui aidera l'usager à comprendre votre programme.

L'exemple qui vous sera montré est un logiciel que moi et mes coéquipiers avons développé pour la librairie Aby Yala (www.abyayala.com). C'était notre projet de fin d'études.

Section pouvant être incluse dans un guide à l'usager

Table des matières

La table des matières doit être incluse dans chaque division et sous division de votre documentation

Nouveauté du logiciel

Indiquez les nouveautés de la version du logiciel s'il existe plusieurs versions

Configuration requise

Indiquez la configuration minimale recommandée pour le logiciel

Manipulation du programme

Indiquez les étapes pour l'installation, l'exécution et la désinstallation de votre programme.
S'il existe plusieurs composants (librairie, dll, base de donnée....) externes nécessaires au bon fonctionnement de votre application,inscrivez les étapes précédentes pour les composants auxquels s'applique cette démarche

Description du programme

Inscrivez une description générale de votre application.

Outils de navigation et menu

Détaillez les outils de navigations et les menus s'il y a lieu

Fonctionnement du programme

Indiquez les étapes nécessaires pour effectuer des traitements. Donnez de l'information sur les options du programme. Les images facilitent l'apprentissage d'un usager.

Force du système

Identifiez les forces de votre programme, les petits plus de votre application

Glossaire

Prévoyez un glossaire si votre documentation contient des termes techniques qu'un usager ne pourrait comprendre.

Document word du projet disponible ici.

samedi 21 mai 2005

Concevoir une application en PHP


Concevoir une application en PHP

Présentation

Lors de la réalisation d'une application le choix du langage de programmation est conditionné par l'utilisation qui sera faite du logiciel. PHP est donc utile si vos utilisateurs sont nombreux et réparti géographiquement, car il ne nécessite pas l'installation d'un logiciel client lourd, un simple navigateur internet suffit.

Dès lors qu'une application contient des données importantes, il est utile de pouvoir contrôler les accès à celles-ci, pour cela une identification de chaque utilisateur est nécessaire. Nous allons voir dans cet article comment structurer son code afin de réaliser une application de gestion complexe.

Création de la structure

Dans un premier temps, il est nécessaire de déterminer la structure de l'application, c'est-à-dire les différents utilisateurs ainsi que les fonctionnalités accessibles à chacun.
Par exemple, pour un logiciel de gestion de notes dans un établissement scolaire, on aura les types d'utilisateurs suivants :

Type utilisateur       Fonctionnalités
Administrateur
  • Ajout/modification/suppression d'utilisateurs
  • Ajout/modification/suppression de classes
Direction
  • Consultation des notes des élèves
Vie scolaire
  • Gestion des absences
  • Modification des classes des élèves
  • Modification des classes des enseignants
Enseignants
  • Saisie des notes
  • Edition de synthèses
  • Editions de bulletins de notes
Elèves
  • Consultation des notes personnelles
Pour faciliter la maintenance de l'application, il peut-être utile d'enregistrer tout cela dans une base de données, on aura donc la base de données suivante :

Nom de la table      Champs de la table
typeUtilisateur
  • num (identifiant)
  • libellé
utilisateur
  • login
  • mot de passe
  • nom
  • prénom
  • type (qui reprend une valeur de num de la table typeUtilisateur)
Chaque fonctionnalité correspond à un élément du menu de l'application, on peut donc les enregistrer dans une base de données :

Nom de la table       Champs de la table
fonctionnalités
  • type (qui reprend une valeur de num de la table typeUtilisateur)
  • menu (qui contient l'élément du menu)
  • action (qui indique l'action associée à la fonctionnalité)
  • libellé (libellé qui apparaît dans le menu)
  • ordre (ordre d'affichage dans le menu)
  • actif (permet de désactiver un élément du menu sans le supprimer)


Exemple de table fonctionnalités complétées :
type menu action libellé ordre actif
'administrateur' 'accueil' 'gestionUtilisateurs' 'Gestion des utilisateurs' 1 vrai
'administrateur' 'accueil' 'gestionClasses' 'Gestion des classes' 2 vrai
'direction' 'accueil' 'consultationNotes' 'ConsultationNotes' 1 vrai
'vie scolaire' 'accueil' 'gestionAbsences' 'Gestion des absences' 1 vrai
'vie scolaire' 'accueil' 'gestionEleves' 'Gestion des élèves' 2 vrai
'vie scolaire' 'accueil' 'gestionEnseignants' 'Gestion des enseignants' 3 vrai
'enseignant' 'accueil' 'saisieNotes' 'Saisie de notes' 1 vrai
'enseignant' 'accueil' 'editions' 'Editions' 2 vrai
'enseignant' 'editions' 'editionsSyntheses' 'Editions de synthèse' 1 vrai
'enseignant' 'editions' 'editionsBulletins' 'Editions de bulletins' 2 vrai

On remarque que cette structure permet de définir des menus et des sous-menus comme on le souhaite et donc de faciliter la maintenance de l'application, ajouter une fonctionnalité ne nécessite pas la relecture de tout le code pour refaire le menu, le menu sera modifié dynamiquement par l'ajout d'un élément dans la base.

Mise en place

Pour utiliser la structure créée, on utilise un fichier "index.php" qui doit définir le type de l'utilisateur et à partir de cela lui afficher le menu correspondant à l'aide d'une fonction menu :

function menu($menu){
        global $type;

        $query="select action,libelle from menu where menu='$menu' and type=$type and actif=1 and ordre>0  order by ordre";
        $result=mysql_query($query);
        $nbCaracteres=0;
        if(mysql_num_rows($result)>0){
                echo "<div id=\\"menu\\">\\n";
                echo "  <table border=0>\\n";
                echo "      <tr>\\n";
                while($row=mysql_fetch_row($result)){
                        echo "          <td>";
                        echo "<a href=\\"./.?action=$row[0]\\">stripslashes($row[1])</a>;
                        $nbCaracteres = $nbCaracteres + strlen($row[1]);
                        echo "       </td>\\n";
                }
                echo "      </tr>\\n";
                echo "  </table>\\n";
        }
}

un switch permet d'amener l'utilisateur sur l'élément souhaité selon la valeur de la variable $action.

Conclusion

Cette méthode permet d'améliorer la maintenabilité d'un logiciel écrit en PHP, il peut être utile de générer un outil de gestion des menus lorsque l'application devient très grosse avec de nombreux types d'utilisateurs différents.

lundi 25 avril 2005

Test, vérification et validation

TEST, VÉRIFICATION ET VALIDATION

La qualité d'un logiciel ne fait malheureusement pas souvent partie des processus du développement logiciel au sein des entreprises. Les entreprises qui ont peu de moyens ou pour lesquelles le temps de mise sur le marché est crucial négligent souvent cette étape du développement logiciel.

La qualité d'un logiciel est directement liée aux caractéristiques qui peuvent être mesurées à l'aide de tests et d'inspections.
Plusieurs problèmes qui peuvent avoir des conséquences majeures sur le projet, peuvent être mis en évidence:
  • Identification des exigences des usagers
  • Implémentations des exigences des usagers
  • Facilité d'utilisation et mise à jour de la documentation
  • Maintenance du système
Ces activités, si elles sont négligées, peuvent causer l'échec d'un projet ou tout au moins l'affecter grandement. Le client peut se retrouver avec un système qui ne lui convient pas et ne l'utilisera pas

Ce processus est souvent appelé l'activité V&V (vérification et validation) dans le métier. Le niveau de v & v ne peut être du même niveau pour n'importe qu'elle système. Ne serait-ce que pour des questions de coûts par exemple. Les mesures misent en place pour le développement d'un système bancaire peuvent s'avérer totalement inutile pour la gestion d'un logiciel de pool de hockey.

Plusieurs questions peuvent faciliter les mesures devant être prises pour un projet: quel est le niveau de qualité devant être atteint, les demandes spécifiques du client, les ressources disponibles, le niveau d'expertise, l'échéancier, le niveau de risque pouvant être pris... Les réponses à ces quelques questions permettent d'avoir un petit aperçu des mesures nécessaires pour assurer un minimum de qualité pour le système à développer. Ces pratiques ne sont trop souvent pas réalisées pour les logiciels commerciaux, il suffit de voir le nombre de mises à jour critiques... Une grande partie des problèmes au niveau de la qualité peuvent être enrayés grâce aux tests. Un article sur les tests peut être trouvé dans la section Génie logiciel de ce site.

Les tests

Cette phase est l'une des plus coûteuses en terme de temps et d'argent, elle peut facilement prendre plus de 30% du cycle de développement. Parmi les tests, on retrouve :
  • les tests unitaires qui sont faits par le programmeur afin que chaque module puisse fonctionner sans erreur de programmation
  • les tests fonctionnels qui sont faits par le programmeur ou un spécialiste afin de s'assurer que les exigences fonctionnelles sont implantées convenablement
  • le test du produit afin de s'assurer que le logiciel s'exécute correctement
  • le test du système afin de vérifier si le logiciel fonctionne sur la machine cible (avec les logiciels et matériel du client)
  • le test de validation qui est fait par le client pour vérifier le niveau de qualité
Malheureusement, la compétitivité du marché semble l'emporter sur la qualité. Livrer un système sans faille ne semble plus possible.

Il est difficile de juger du moment où il est opportun d'arrêter les tests. Il est possible de se baser sur des coûts économiques: le coût d'une éventuelle panne du système coûterait plus cher que le coût des tests. Les risques doivent être pris en considération lorsque les tests sont arrêtés.

Automatisation


La phase de tests est souvent réalisée de façon manuelle. Or cette étape peut être de plus en plus automatisée. Certes, il y a une phase d'adaptation au niveau du logiciel, mais le temps et l'argent investis ne seront pas perdus.

Des logiciels qui génèrent des entrées pour un système existent. Les logiciels de ce type permettent de voir comment le logiciel réagira avec 8, 10.. Caractères lorsque le logiciel n'en gère que 5 par exemple. Il est ainsi possible de voir les cas limites du système. Un rapport est créé et les tests passés ou échoués peuvent être rapidement vus. Une fois que les cas désirant être testés sont créés, ils pourront être de nouveau exécutés à chaque version du logiciel afin de voir si de vieux problèmes ne sont pas revenus. En plus de pouvoir être utilisés dans d'autres versions du système, ils peuvent être utilisés à diverses phases des tests. Au final, les tests sont gérés de façon centralisée. Les tests et résultats des tests sont accessibles à tous.

Des outils d'analyse de code existent aussi, ils permettent de savoir si certains standards ont été suivis, de cerner d'éventuels problèmes. Un autre outil facile à mettre en oeuvre est le gestionnaire de suivi de problème. Un exemple de ce type de logiciels est bugzilla. Ce type d'application permet de voir les problèmes fixés, de nouvelles caractéristiques désirées...
Afin d'assurer une réussite des approches vues dans cet article, l'entreprise doit s'assurer de la participation de tous. Plus nos processus de développement logiciels sont défaillants, plus le niveau d'efforts sera exigence. Un suivi plus précis de la gestion du projet devra être réalisé.

Du temps devra être pris pour bien documenter les étapes de développement du système. Les participants aux projets devraient tous connaître les ressources mises à leurs dispositions pour augmenter la qualité du système. Savoir qu'on a des ressources n'est pas tout, il faut aussi les utiliser. Une bonne communication s'avère cruciale pour espérer une réussite d'un projet informatique.

dimanche 24 avril 2005

Les fonctions


FONCTION

Tout comme dans la majorité des autres langages de programmation, il est possible de créer des fonctions.

Simple fonction

La définition d'une fonction est similaire au langage C.

function bonjour()
{
  echo "bonjour"
}

il est aussi possible de faire:

bonjour()
{
  echo "bonjour"
}

Il suffit d'invoquer le nom de la fonction pour qu'elle soit appelée. La définition de la fonction doit être fait avant son appel.

#!/bin/bash
bonjour()
{
  echo "bonjour"
}

bonjour

Argument

Il est possible de passer des arguments à une fonction. Dans la fonction, il suffit de vérifier la valeur de $1, $2...

#!/bin/bash
information()
{
  if [ -n "$1" ]
  then
    echo $1;
  else
    "Aucun paramètre"
  fi
}

information "salut"
#!/bin/bash
information()
{
  if[ -n "$1"]
    echo $1
  else
    echo "Aucun paramètre";
  fi
  return 0
}

information
information "salut"

Argument

Nous allons maintenant créer une fonction qui retourne une valeur.
function min()
{
  if [ -n "$1" ] && [ -n "$2"  ]
  then
    if [ "$1" -lt  "$2" ]
    then
      return $1;
    else
      return $2;
    fi
  fi
}
min 112 13
echo "$? est la plus petite valeur"

Essayer de mettre une valeur supérieure à 256 comme argument.
Prenez note qu'une fonction ne peut renvoyer une valeur supérieure à 256. Cette contrainte provient des codes de sortie. Dans les nombres négatifs, il est possible d'aller beaucoup plus loin. Il suffit d'utiliser une variable globale pour pallier à ce problème.

VAL=
function min()
{
  if [ -n "$1" ] && [ -n "$2"  ]
  then
    if [ "$1" -lt  "$2" ]
    then
      VAL=$1
    else
      VAL=$2
    fi
  fi
}
min 1132 1300

echo "$VAL est la plus petite valeur "

Prenez note de la syntaxe de la déclaration de la variable VAR.
Vous devez utiliser une variable si vous désirez retourner une chaîne de caractère.
Prenez note qu'une variable déclaré dans une fonction à une portée globale au script. Elle peut donc être utilisé partout ailleurs. Pour éviter cela, il faut mettre avant le nom de la variable local lors de son initialisation.

local prenom="paul"

Nous avons complété la partie traitant des fonctions. Un script avec tous les exemples peut téléchargez ici

dimanche 17 avril 2005

Les opérations arithmétiques


LES OPÉRATIONS ARITHMÉTIQUES

Telles que la majorité des langages, les opérations restes les mêmes : +, -, *, /. C'est assez standard comme syntaxe. Il y a cependant quelques différences pour certaines. Il est nécessaire de mettre le mot: let pour plusieurs opérations.

Exposant

Nous devons employer : ** si on désire effectuer l'opération x^y. La commande ci-dessous retournera 125.
let "x=5**3"
echo $x

Modulo

Modulo retourne le reste de la division. On obtiendra donc 2 avec la commande suivante.
let "x=125%3"
echo $x

Constante

Il est possible comme plusieurs langages, d'employer une syntaxe raccourcie pour les opérations : +, -, *, /, %. Ces instructions deviennent alors: +=, -=, *=, /=, %=.
JOURS=" Lundi Mardi Mercredi Jeudi Vendredi Samedi Dimanche"
for jours in `echo $JOURS`
do
  let "x +=100$"
done

Notez qu'on aurait pu changer += par une des autres instructions qu'on a vues plus haut: -=, *=...*

Contrainte

Bash convient parfaitement pour des opérations sans trop de complexité. Bash emploie des entiers 32bits pour les nombres donc il est impossible d'utiliser des nombres en dehors de l'intervalle : 2147483648, 2147483647 sans obtenir un message d'erreur. Si vous avez une version moindrement récente de Bash cette contrainte est enlevée. Les nombres à virgule flottante ne peuvent être employés. BC ou une librairie mathématique externe doit être utilisée.
BC est un langage qui permet de faire de multiples opérations avec les nombres. Il a une syntaxe similaire au C.

x=$(echo "2+1.3" | bc)
echo $x

Dans le code ci-dessus, il y a quelques nouveautés. Le contenu du echo à l'intérieur de la parenthèse est envoyé à bc. L'emploi de |, envoie la sortie d'une commande à une autre. C'est ce qu'on appelle un pipe (tuyau).

Nous avons complété la partie traitant des opérations arithmétiques. Un script avec tous les exemples peut être téléchargé ici

Migration d’une application Spring Boot 2.2 vers Spring Boot 4.0 : retour d’expérience concret

 En 2019, nous avons développé une application métier basée sur : Java 8 Spring Boot 2.2.7 Gradle 6.6.1 Thymeleaf Boots...