cedric dumoulin - cristal.univ-lille.fr
Post on 17-Oct-2021
15 Views
Preview:
TRANSCRIPT
Cedric Dumoulin
Bibliographie Spring IO
http://spring.io/ Developing a Spring Framework MVC application
step-by-step (2.5) http://docs.spring.io/docs/Spring-MVC-step-by-step/
Spring MVC Framework Tutorial http://www.tutorialspoint.com/spring/spring_web_mvc_fra
mework.htm Wikipedia
http://en.wikipedia.org/wiki/Spring_Framework Quick start
http://projects.spring.io/spring-framework/#quick-start
Guides Accessing Data with JPA
http://spring.io/guides/gs/accessing-data-jpa/
Serving Web Content with Spring MVC (2016) http://spring.io/guides/gs/serving-web-content/
Spring http://spring.io/
Framework créé en 2002 !!
Un des premier à proposer « l’inversion de contrôle » Toujours en évolution
aujourd’hui : « Spring helps development teams everywhere build simple, portable, fast and flexible JVM-based systems and applications.»
Permet aussi de : Créer des application WEB
En alternative, remplacement ou addition des EJB
Qu’est-ce que Spring ? A l’origine, un framework
S’appelle maintenant Spring Framework Aujourd’hui, un ensemble de projets :
Spring Framework Constitué de caractéristiques (features) organisées en
modules (Core Container, Web, AOP …)
Spring Framework Features Core technologies:
dependency injection, events, resources, i18n, validation, data binding, type conversion, SpEL, AOP.
Testing: mock objects, TestContext framework, Spring MVC Test,
WebTestClient. Data Access:
transactions, DAO support, JDBC, ORM, Marshalling XML. Spring MVC and Spring WebFlux web frameworks. Integration:
remoting, JMS, JCA, JMX, email, tasks, scheduling, cache. Languages:
Kotlin, Groovy, dynamic languages.
SPS - Spring Tool Suite Plugins Eclipse pour le développement avec Spring
https://spring.io/tools Installation
https://github.com/spring-projects/sts4/wiki/Installation
Par le marketplace (version 3.x, obsolete) Ou all-in-one distribution Ou Update site (pour ajouter dans une application
existante).
Instalation par le marketplace Choisir le plugin
correspondant à votre version d’Eclipse
Instalation par updatesite https://github.com/spring-
projects/sts4/wiki/Installation
Choisir le updatesite correspondant à votre version d’Eclipse
Installer un exemple avec STS File -> New -> Import Spring
Getting Started Content
Installe aussi les jars necessaire à la compilation et l’execution
Ce sert de Maven les jar sont dans .m2
http://spring.io/guides/gs/sts/
Exécuter un exemple Construire le jar et le lancer :
mvn clean package && java -jar target/gs-serving-web-content-0.1.0.jar
Notes: Ce n’est pas un war Le jar contient un serveur embarqué
Projet ‘boot’
Certain fichiers de base manquent (web.xml, …) Ils sont déduits des classes et annotations
Approche non recommandé pour la production (et même pour le développement).
mvn clean package && java -jar target/gs-serving-web-content-0.1.0.jar
Atelier Objectifs :
Installer STS 4 Faire une première applications Spring
Working a Getting Started guide with STS
https://spring.io/guides/gs/sts/ Installer STS 4 :
https://github.com/spring-projects/sts4/wiki/Installation Prendre : common + distribution
Différentes approches Eclipse
Créer un projet Web dynamique Le rendre « Maven » compatible Ajouter les dépendances
SPS Créer un projet « Spring legacy » Choisir projet Web MVC Le projet est prêt a fonctionner
Spring Boot C’est Spring + des librairies permettant de faire tourner l’appli
comme une appli Java (avec un main() )
Ateliers Building an Application with Spring Boot
https://spring.io/guides/gs/spring-boot/
Atelier Spring MVC – Atelier 1
Créer un nouveau projet Spring dans Eclipse (avec STS) Nom : ipint.spring.atelier2 Packages : ipint.spring.atelier2
Tester !!
Rôle d’un contrôleur Un contrôleur sert à traiter une requête http
http://monserveur/monappli/unepage?name=jule Spring permet
D’associer l’url de la requête avec une méthode d’un contrôleur
D ’associer les paramètres de la requête avec les arguments de la méthode
D’associer des objets du contexte de la requête avec les arguments de la méthode
@Controller public class HomeController { @RequestMapping(value = "/home", method = RequestMethod.GET) public String home(Locale locale, Model model) { String formattedDate = getFormattedDate(locale); model.addAttribute("serverTime", formattedDate ); return "home_rendu"; }
Controller simple Déclare un contrôleur
L’url associée a ce ctrl
Le model qui sera passé à la page
Nom logique de la page
Un attribut qui sera passé à la page
@Controller public class HomeController { @RequestMapping(value = "/home", method = RequestMethod.GET) public String home(Locale locale, Model model) { String formattedDate = getFormattedDate(locale); model.addAttribute("serverTime", formattedDate ); return "home_rendu"; }
Controller simple Spécifie le type de
requete (GET ou POST)
Demande l’objet Locale
Controller Peut contenir plusieurs méthodes avec différentes URL Les paramètres des méthodes sont « libre »
C’est le type ou l ’annotation qui est détecté L’annotation @RequestMapping peut se faire sur la
classe Toute les url de méthodes sont alors relative a l’url de la
classe.
Spécifier le type de requêtes Optionnel GET
Le plus courant : demande une page POST
Suite à la soumission d’un formulaire
2 possibilités @RequestMapping(value = "/home", method = RequestMethod.GET)
@GetMapping(value = "/home")
Atelier Serving Web Content with Spring MVC
https://spring.io/guides/gs/serving-web-content/
Atelier Spring MVC – Atelier 2 Créer un nouveau controleur
Différentes moteurs de rendus peuvent être utilisées JSP Thymeleaf REST Tiles …
Indépendant du contrôleur
Différentes moteurs de rendus peuvent être utilisées Spring Boot includes auto-configuration support for the
following templating engines: FreeMarker Groovy Thymeleaf Mustache
Il faut spécifier la dépendance vers la library du framework
concerné Dans graddle ou Maven Spring Boot detectera la dépendance et auto-configurera
l’application
Comment passer des parametres Soit un par un
Soit plusieurs a l'aide d'un form
<a href="params.html?name=skywalker">skywalker !</a>
Soit plusieurs a l'aide d'un form <form action="forms.html">
<table> <tr> <td>name : </td><td><input type="text" name="name"/></td> </tr> <tr> <td>surnname : </td><td><input type="text" name="surname"/></td> </tr> <tr> <td>mail : </td><td><input type="text" name="mail"/></td> </tr> <tr> <td> </td><td><input type="submit" title="Send !"/></td> </tr> </table> </form>
Comment les recuperer ? Dans un controleur Soit un par un avec @RequestParam
@RequestMapping("/greeting") public String greeting( @RequestParam(value="name", required=false, defaultValue="World") String name, Model model) { logger.info("greeting! "); model.addAttribute("name", name); // We should put the file extension in order to let the //ViewResolver filter set in config.xml works return "greeting.html"; }
Soit a l'aide d'un objet Utiliser @ModelAttribute
@RequestMapping("/forms") public String receiveForms(@ModelAttribute Person person, Model model, Locale locale) { model.addAttribute("name", person.getName()); return "forms_rendu"; }
Etapes pour utiliser un formulaire Ecrire deux pages de rendus
l'une affichant le formulaire l'autre affichant le resultat de la soumission du
formulaire Ecrire deux controleurs
L'un pour afficher le formulaire l'action du formulaire designe l'url du controleur traitant le
formulaire
L'autre pour recuperer les params du formulaire, puis les afficher dans une page
Atelier Handling Form Submission
https://spring.io/guides/gs/handling-form-submission/
Atelier 4 - récupérer un paramètre Atelier - récupérer plusieurs paramètres dans un objet
Formulaire avancé Offre plus de possibilité que le formulaire HTML S’utilise avec un balise spécifique
JSP
<form:form modelAttribute="person" method="POST" action="${pageContext.request.contextPath}/personjsp.html"> <form:input path="name" /> <input type="submit" value="Send !" /> </form:form>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
Thymeleaf
<!DOCTYPE HTML> <html xmlns:th="http://www.thymeleaf.org"> <head> <title>Getting Started: Handling Form Submission</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> </head> <body> <form action="#" th:action="@{/person.html}" th:object="${person}" method="post"> <p>name: <input type="text" th:field="*{name}" /></p> <p>surname: <input type="text" th:field="*{surname}" /></p> <p>age: <input type="text" th:field="*{age}" /></p> <p><input type="submit" value="Submit" /> <input type="reset" value="Reset" /></p> </form> </body> </html>
Bibliographie Validating Form Input
[2018] https://spring.io/guides/gs/validating-form-input/
Validation Spring MVC Form Handling Tutorial and Example
[2017] http://www.codejava.net/frameworks/spring/spring-mvc-form-handling-tutorial-and-example
Doc [2018] https://docs.spring.io/spring/docs/5.1.2.RELEASE/spring-
framework-reference/core.html#validation [2018] https://docs.spring.io/spring/docs/5.1.2.RELEASE/spring-
framework-reference/core.html#validation-beanvalidation
Documentation http://docs.spring.io/spring/docs/3.2.5.RELEASE/spring-
framework-reference/htmlsingle/#validation
Spring Validation Example – Spring MVC Form Validator [2016] http://www.journaldev.com/2668/spring-validation-
example-mvc-validator Exemples avec 3 formes de validation (javax.validation, custom
annotations, custom validator)
Spring MVC Form Validation Example with Bean Validation API [2018] http://www.codejava.net/frameworks/spring/spring-
mvc-form-validation-example-with-bean-validation-api
Que valider ? Il faut valider pour se garantir :
• De mauvaises saisies dans les formulaires • De données saisies non valables pour le métier
Les mauvaises saisies peuvent être détectés par:
la conversion de la requête http objet command Les contraintes métiers peuvent être détectés par:
des objets de validation
Validation Action de valider des données en fonction du métier
ex: 0<= age <150
Plusieurs possibilités avec Spring les technique se sont empilées avec le temps
Les plus récentes: Bean Validation 1.0 (JSR-303) and Bean Validation 1.1 (JSR-349)
Bean Validation Principe:
annote le bean : @NotEmpty, @Email, @Size … Spécifie les messages d’erreurs
import javax.validation.constraints.Size; import org.hibernate.validator.constraints.Email; import org.hibernate.validator.constraints.NotEmpty; public class User { @NotEmpty @Email private String email; @NotEmpty(message = "Please enter your password.") @Size(min = 6, max = 15, message = "Your password must between 6 and 15 characters") private String password; . . . // getters + setters }
Plusieurs sources possible pour les annotations standard : javax.validation hibernate : org.hibernate.validator.constraints spring : org.springframework.format.annotation …
On peut definir ses propres annotations !!
Voir [Spring Validation Example – Spring MVC Form Validator]
Validation explicite lors de la conversion Utilise @Valid (javax.validation)
@RequestMapping(value = "/login", method = RequestMethod.POST) public String doLogin(@Valid User userForm, BindingResult result, Model model) { if (result.hasErrors()) { return "LoginForm"; } return "LoginSuccess"; } }
Objet contenant les erreurs validation
Déclenche la validation
• BindingResult result contient les éventuelles erreurs de conversion doit être placé immédiatement après le @ModelAttribute auquel il se réfere
Autre méthode de validation possible Définir des objets « Validator »
Voir [Spring Validation Example – Spring MVC Form Validator]
Principe Avoir un objet de type BindingResult dans le context
de la page de rendu L’objet contient des erreurs On peut utiliser les tags de gestion d’erreurs dans la
page de rendu
BindingResult BindingResult est créé et rempli lors de la validation Il est par défaut passé au context de la page Il faut le déclarer immédiatement après l’o validé l’objet
validé Il peut y avoir plusieurs paires objet validé/bindingResult
@RequestMapping(value = "/login", method = RequestMethod.POST) public String doLogin(@Valid User userForm, BindingResult result, Model model) { if (result.hasErrors()) { return "LoginForm"; } return "LoginSuccess"; } }
Affichage des erreurs - JSP
Le tag <form:errors .. /> permet d’afficher le message d’erreur uniquement si la propriété indiquée est en erreur.
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%> ... <form:form action="login" commandName="userForm"> … <form:input path="email" size="30"/></td> <form:errors path="email" cssClass="error"/> … </form:form>
<form:errors path="email" cssClass="error"/>
Affichage des erreurs - JSP <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
... <form:form action="login" commandName="userForm"> <tr> <td align="left" width="20%">Email: </td> <td align="left" width="40%"><form:input path="email" size="30"/></td> <td align="left"><form:errors path="email" cssClass="error"/></td> </tr> <tr> <td>Password: </td> <td><form:password path="password" size="30"/></td> <td><form:errors path="password" cssClass="error"/></td> </tr> <tr> <td></td> <td align="center"><input type="submit" value="Login"/></td> <td></td> </tr> </form:form>
Affichage des erreurs Thymeleaf
<form action="#" th:action="@{/person.html}" th:object="${person}" method="post"> <table> <tr> <td>Name:</td> <td><input type="text" th:field="*{name}" /></td> <td th:if="${#fields.hasErrors('name')}" th:errors="*{name}">Name Error</td> </tr> . . . </table> </form>
<td th:if="${#fields.hasErrors('name')}" th:errors="*{name}">Name Error</td>
Etapes Validation
Ajouter les dépendances pour la validation Annoter les classes à valider Annoter les arguments a valider dans les controleurs
Affichage des erreurs Modifier les formulaires ou les pages pour afficher les
erreurs Modifier les controleurs pour utiliser les pages avec
affichage d’erreurs.
Atelier Atelier 2 Spring MVC
Formulaire et validation (thymeleaf)
Demo
Bibliographie [2018] Internationalization in Spring Boot
http://www.baeldung.com/spring-boot-internationalization
[old] Spring MVC Internationalization (i18n) and Localization (L10n) Example https://www.journaldev.com/2610/spring-mvc-
internationalization-i18n-and-localization-l10n-example
Bibliographie http://viralpatel.net/blogs/spring-3-mvc-
internationalization-i18n-localization-tutorial-example/
I18n avec changement possible du local : https://www.journaldev.com/2610/spring-mvc-
internationalization-i18n-and-localization-l10n-example http://www.baeldung.com/spring-boot-
internationalization
Principe Utilise la notion de « Locale » : Pays_langue
FR_fr, US_en
Dans le code, on utilise des constantes à la place du texte thymleaf JSP
Les constantes sont définies dans des fichiers Un fichier par langue
<spring:message code="page.home.hello"/>
<h1 th:text="#{greeting}"></h1>
Fichiers de langues Contiennent la définition des constantes
Pairs nom=valeur A placer dans
src/main/resources Un fichier par langue Un fichier par défaut Tous les fichiers ont le même nom
Mais des extensions en fonction du locale: messages.properties messages_FR_fr.properties
Alternatives: Des pages différentes en fonction du locale
Possible avec Tiles
Spring MVC Les fichiers properties Permet d’utiliser des constantes dans les pages Les définitions sont dans des fichiers *.properties Dans répertoire src/main/resource/*
fichier par défaut
fichier local = fr
pas définit = venant du fichier par défaut
I18n avec Spring et JSP
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <%@taglib uri="http://www.springframework.org/tags" prefix="spring"%> <%@ page session="false" %> <html> <head> <title><spring:message code="page.home.title"/></title> </head> <body> <h1> <spring:message code="page.home.hello"/> </h1> <P> <spring:message code="page.home.timeOnServer"/> ${serverTime}. </P> </body> </html>
La taglib utilisée
Le message
I18n avec Spring et thymeleaf Utiliser la syntaxe #{key}
<h1 th:text="#{greeting}"></h1>
I18n avec Spring et thymeleaf
<!DOCTYPE HTML> <html xmlns:th="http://www.thymeleaf.org"> <head> <title th:texte="#{home.title}" /></title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> </head> <body> <h1 th:text="#{home.title}"></h1> <p th:texte="#{home.welcome}" > ${serverTime}. </p> </body> </html>
Laisser l’utilisateur choisir sa langue Il faut ajouter un choix du local Il faut prendre en compte le changement
voir tuto
[2018] http://www.baeldung.com/spring-boot-internationalization
[2016] http://viralpatel.net/blogs/spring-3-mvc-internationalization-i18n-localization-tutorial-example/
Changer le locale dynamiquement Ajouter un parametre locale=?? à la requête
Peut se faire grace à des liens dans les pages
Prendre en compte le changement dynamique dans
l’application Configurer Spring !
http://monsite/monappli/page.html?locale=en
<a href="/home?locale=en" >en</a>, <a href="/home?locale=fr" >fr</a>
Atelier Atelier 2 Spring MVC
I18n
Notion de composants Injection
Bibliographie [2017] Spring Beans @Component vs @Bean
https://therealdanvega.com/blog/2017/05/17/spring-component-vs-bean
Components et Bean Une application Spring et composée de Bean pouvant être
connecté entre eux (wired)
Un bean est une instance d’une classe ou d’un Component Un Component est une classe annoté @Component
MyServices1 MyDao1
MyServices2 Repo1
Components Classe annotée @Component Découverte lors du scan des paquetages Par défaut, Spring crée un bean par classe annotée
Nom : nom de la classe, mais 1er lettre en minuscule
Autres tags possible : @Component, @Named
@Controller, @Service, @Repository Ce sont des Components particuliers
Connecter les composants Injection Connexion par injection
Déclare une propriété ou un attribut Ajoute l’annotation @Inject,ou @Autowired Spring injectera une instance du component (ie un
Bean) du type demandé
Même principe que JEE
Déclarer un composant Par défaut, le nom est le nom simple de la classe (commençant par une
minuscule) 2 tags équivalent: @Component et @Named On peut spécifier le nom
@Component("injectedComponent")
/** * A simple bean that will be injected elsewhere */ @Component public class InjectedBean { private String firstname = "John"; private String lastname = "Doe"; //.. Getter an setter .. }
Déclare un composant
Injecter un composant @Inject (et @Autowired, @Resource)
Peut se faire sur un attribut, un setter, … Recherche si il existe un bean du nom de l’attribut, et compatible avec le type Si non recherche un bean compatible avec le type Si non erreur
On ne peut pas spécifier le nom Sauf pour @Resource(‘name’)
@Controller public class HomeController { /** * Try to inject a bean */ @Inject protected InjectedBean injectedBean; // .. }
Spring injecte le bean du bon type
Création explicite d’un Bean Spring permet de créer explicitement le Bean Usage:
Pour avoir une initialisation particulière Pour créer les Beans de configuration
Ce fait dans une classe de @Configuration
Création explicite d’un Bean Le nom du bean sera le nom de la méthode (ici superUser) Peut aussi se faire dans un fichier de configuration XML
@Configuration public class ApplicationConfig { @Bean public User superUser() { return new User("Dan","Vega"); } }
Atelier Atelier 2 Spring MVC
Components et Injection
Architecture type
@Component class MyServices1
@Component class MyDao1
@Component class MyServices2
@Component class Repo1
@Controler class MyControler
Page rendu
présentation Présentation / domaine / persitance
Bonnes pratiques Pas de bussiness dans les controleurs Déléguer aux « services » Eviter les objets métier dans la couche présentation
Bibliographie Quelques principes d’architecture d’applis Web
Java/JEE [2014] https://jobprod.com/quelques-principes-
darchitecture-dapplis-web-javajee/
Comment relier les deux
Bibliographie [2018] Integration Guide for Spring and EJB
https://www.baeldung.com/spring-ejb
Chapter 18. Enterprise Java Beans (EJB) integration https://docs.spring.io/spring/docs/2.5.1/reference/ejb.ht
ml https://docs.spring.io/spring/docs/4.3.x/spring-
framework-reference/html/ejb.html
Injecter des EJB Session dans Spring C’est possible !
Un Component Bean Session peut être vu comme un Component Spring
En deux temps:
déclarer le Bean Session en tant que Component Spring injecter le component à l’endroit où on veut l’utiliser
Principe Déclarer la factory pour créer le bean
Dans une class @Configuration Spring appelera la méthode quand nécessaire
Renvoyer l’interface du Bean On la récupère par lookup
@Bean public HelloStatelessWorld helloStatelessWorld(Context context) throws NamingException { return (HelloStatelessWorld) context.lookup(this.getFullName(HelloStatelessWorld.class)); }
Context JNDI On a aussi besoin du Context JNDI
Sert à demander un objet par son nom JNDI Prend en charge la connexion avec le serveur JNDI (ex: Glassfish)
On le crée a l’aide d’un Bean Spring On peut lui passer des properties de création
@Bean public Context context() throws NamingException { Properties jndiProps = new Properties(); jndiProps.put("java.naming.provider.url", "http-remoting://localhost:8080"); return new InitialContext(jndiProps); }
Utiliser le Bean EJB On le récupère par injection
@Autowired ou @Inject @Controller public class HelloController { @Autowired protected HelloWordBeanRemote helloStatelessWorld; @RequestMapping(path="/") public String sayHello( Model model) { String msg = helloStatelessWorld.sayHello("titi"); model.addAttribute("msg", msg); return "hello"; } }
Injecter le Bean EJB dans un contrôleur Méthode classique avec @Inject
@Controller public class HomeController { @Inject protected helloStatelessWorld injectedBean; /** * Simply selects the home view to render by returning its name. */ @RequestMapping(value = "/", method = RequestMethod.GET) public String home(Locale locale, Model model) { // … if( injectedBean == null ) { logger.info("The bean is not injected !."); return "home"; } // Injection works ! model.addAttribute("myInjectedBean", injectedBean ); return "success"; }
Atelier ateliers 1
Atelier – Spring et JavaEE
ateliers-3-ProjetBiblio.pdf
Objectifs Compléter l’application Bibliothèque
Couche présentation avec Spring MVC Connecter à la couche métier réalisé avec EJB et JPA
Identifier les problèmes de mise en œuvre
Les résoudres et les documenter dans un doc à rendre
Quelques indications L’application est composé de plusieurs projets
Attention aux dépendances
Quelques indications L’application tourne sur plusieurs serveurs (2 + db)
Attention aux dépendances, à la répartition des paquetages Le client nécessite gf-client.jar Problème avec les ports (8080)
Délivrables L’application sous GIT Un document
Voir ateliers-3-ProjetBiblio.pdf
Bibliographie [2014] Quelques principes d’architecture d’applis Web
Java/JEE https://jobprod.com/quelques-principes-darchitecture-
dapplis-web-javajee/ [2007] Spring : théorie & pratique – Arcitecture
https://zekey.developpez.com/articles/spring/#La
top related