Spring MVC Framework Tutorial (PDFDrive)
Spring MVC Framework Tutorial (PDFDrive)
Bibliographie
Spring IO
[Link]
Developing a Spring Framework MVC application
step-by-step (2.5)
[Link]
Spring MVC Framework Tutorial
[Link]
[Link]
Wikipedia
[Link]
Quick start
[Link]
Guides
Accessing Data with JPA
[Link]
view2
appli3 pages view2
url=ctrl3
view3
view2
reponse
Rappel Spring MVC
viewResolver
déclaré ds spring-
[Link]
view2
appli3 pages view2
url=ctrl3
view3
view2
reponse
Tester !!
Rôle d’un contrôleur
Un contrôleur sert à traiter une requête http
[Link]
Spring permet
de mapper l’url de la requête avec une méthode d’un
contrôleur
De mapper les paramètres de la requête avec les
arguments de la méthode
De mapper des objets du contexte de la requête avec les
arguments de la méthode
Controller simple Déclare un contrôleur
[Link]("serverTime", formattedDate );
[Link]("serverTime", formattedDate );
return "home_rendu";
}
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 = [Link])
@GetMapping(value = "/home")
Atelier
Créer un nouveau controleur
Différentes moteurs de rendus
peuvent être utilisées
JSP
Thymeleaf
Tiles
…
Indépendant du contrôleur
ViewResolver
Objets de configuration
Sert à mapper
Le nom logique de la vue (renvoyé par un controleur)
Avec la ressource (le nom du fichier contenant la vue)
<beans:bean class="[Link]">
<beans:property name="templateEngine" ref="templateEngine" />
<!-- NOTE 'order' and 'viewNames' are optional -->
<beans:property name="order" value="1" />
<beans:property name="viewNames" value="*.html,*.xhtml" />
</beans:bean>
Thymeleaf – Déclaration du moteur
Fait référence à un templateResolver
Il faut le déclarer
<beans:bean id="templateEngine"
class="[Link]">
<beans:property name="templateResolver" ref="templateResolver" />
<!-- Enabling the SpringEL compiler with Spring 4.2.4 or newer
can speed up -->
<!-- execution in most scenarios, but might be incompatible
with specific -->
<!-- cases when expressions in one template are reused across
different data -->
<beans:property name="enableSpringELCompiler" value="true" />
</beans:bean>
Thymeleaf – Déclaration du
TemplateResolver
<beans:bean id="templateResolver"
class=
"[Link]">
<beans:property name="prefix" value="/WEB-INF/templates/" />
<beans:property name="suffix" value=".html" />
<!-- HTML is the default value, added here for the sake of
clarity. -->
<beans:property name="templateMode" value="HTML" />
<!-- Template cache is true by default. Set to false if
you want -->
<!-- templates to be automatically updated when modified. -->
<beans:property name="cacheable" value="false" />
</beans:bean>
Thymeleaf – Dépendances
<!-- [Link]
<dependency>
<groupId>[Link]</groupId>
<artifactId>thymeleaf-spring4 </artifactId>
<version>[Link]</version>
</dependency>
Thymeleaf – Exemple
<!DOCTYPE html>
<html xmlns="[Link]
xmlns:th="[Link]
<head>
<title>Hello World Thymeleaf!!</title>
<meta http-equiv="Content-Type" content="text/html;
charset=UTF-8" />
</head>
<body>
Server time :
<p th:text="${serverTime}">Hello World Thymeleaf Offline!!</p>
</body>
</html>
Etapes
Ajouter les dependances
Creer le repertoire pour les templates thymleaf
Declarer les beans de configuration
Creer un controleur utilisant une page de rendu
thymeleaf
Bibliographie
[Link]
[Link]#views-and-view-resolvers-in-spring-mvc
Atelier
Atelier Utiliser une autre technique de rendu
Comment passer des parametres
Soit un par un
@RequestMapping("/forms")
public String receiveForms(@ModelAttribute Person person,
Model model, Locale locale) {
[Link]("name", [Link]());
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
récupérer un paramètres
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
<%@ taglib uri="[Link] prefix="c"%>
<%@ taglib
prefix="form" uri="[Link]
<form:form modelAttribute="person"
method="POST"
action="${[Link]}/[Link]">
Validator Objects
Déclare et utilise des objets de validations
import [Link];
import [Link];
. . . // getters + setters
}
Validation explicite
lors de la conversion
Utilise @Valid (JSR)
if ([Link]()) {
return "LoginForm";
}
return "LoginSuccess";
}
}
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
if ([Link]()) {
return "LoginForm";
}
return "LoginSuccess";
}
}
Affichage des erreurs - JSP
<form:errors path="email" cssClass="error"/>
fichier local = fr
<head>
<title th:texte="#{[Link]}" /></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<h1 th:text="#{[Link]}"></h1>
</body>
</html>
Laisser l’utilisateur
choisir sa langue
Il faut ajouter un choix du local
Il faut prendre en compte le changement
voir tuto
[2017] [Link]
internationalization
[2016] [Link]
internationalization-i18n-localization-tutorial-example/
Changer le locale dynamiquement
Ajouter un parametre locale=?? à la requête
[Link]
Ajouter un intercepteur
Pour intercepter le parametre locale
<interceptors>
<beans:bean class=
"[Link]">
<beans:property name="paramName" value="locale" />
</beans:bean>
</interceptors>
Etapes pour internationaliser
Ajouter les dépendances
Créer les fichiers ressources
Dans src/main/resources
Configurer Spring:
Le bean pour chercher les resources
Le bean interceptor pour changer la localisation
dynamiquement
Le bean pour maintenir la localisation
Localiser les pages (utiliser les codes a la place du texte)
JSP
Thymeleaf
Modifier les pages pour permettre le choix du locale
Atelier
Créer un nouveau projet Spring. Spring génère une
page « home ». Internationaliser cette page.
Tous les sites proposent
des pages cohérentes
Avec un header, un footer, un body, un
menu …
Faut-il coder ces éléments dans toutes les
pages ?
Et si on doit modifier le footer, faut-il alors
modifier toutes les pages ?
Solution :
Utiliser un framework permettant de
separer le header, le footer, le body et le
menu …
Ex: Tiles
Principe
Définir une seule fois les parties communes:
Un header, un footer un main menu
Assembler les pages
Seule le body change
il faut coder celui-ci à part.
Une page == body + parties communes
Vous définissez le body
Le framework ce charge de construire la page en
assemblant les parties pour vous
Plusieurs implémentations
Tiles
Initialement développé pour Struts
Utilisées dans de nombreux moteurs (encore
aujourd’hui)
Pour JSP
Pour Thymeleaf
utiliser thymeleaf-layout-dialect
[Link]
[Link]
Mise en œuvre avec Tiles
[Link] [Link]
[Link]
[Link] [Link]
[Link] [Link]
<tiles-definitions>
<definition name= "view1" extends="classicLayout ">
<put-attribute name="title" value="Another Title"/>
<put-attribute name="body"
value="/WEB-INF/views/[Link]"/>
</definition>
</tiles-definitions>
[Link]
(attention aux pieges )
<%@ page contentType="text/html;charset=UTF-8"%>
<%@ taglib uri="[Link] prefix="tiles"%>
<!DOCTYPE html>
<html lang="en" class="no-js">
<head>
<meta charset="UTF-8">
<title><tiles:insertAttribute name="title" ignore="true" /></title>
<tiles:insertAttribute name="stylecss" />
</head>
<body>
<tiles:insertAttribute name="header" />
<tiles:insertAttribute name="body" />
<tiles:insertAttribute name="footer" />
<tiles:insertAttribute name="scriptjs" />
</body>
</html>
Dépendances Maven
[Link]
Il faut :
tiles-jsp
tiles-core
tiles-templates
tiles-api
tiles-servlet
<dependency>
<groupId>[Link]</groupId>
<artifactId>tiles-core</artifactId>
<version>${tiles-version}</version>
Ajouter les
</dependency>
<dependency>
<groupId>[Link]</groupId>
dépendances <artifactId>tiles-jsp</artifactId>
<version>${tiles-version}</version>
</dependency>
<dependency>
<groupId>[Link]</groupId>
<artifactId>tiles-api</artifactId>
<properties> <version>${tiles-version}</version>
... </dependency>
<tiles-version>3.0.8</tiles-version> <groupId>[Link]</groupId>
</properties> <artifactId>tiles-servlet</artifactId>
<version>${tiles-version}</version>
</dependency>
<dependency>
<groupId>[Link]</groupId>
<artifactId>tiles-template</artifactId>
<version>${tiles-version}</version>
</dependency>
Configurer Spring
<beans:bean id="tilesConfigurer"
class="[Link]">
<beans:property name="definitions">
<beans:list>
<beans:value>/WEB-INF/views/tiles/[Link]</beans:value>
<beans:value>/WEB-INF/views/**/[Link]</beans:value>
</beans:list>
</beans:property>
</beans:bean>
<beans:bean id="tilesViewResolver"
class="[Link]">
<beans:property name="viewClass">
<beans:value>
[Link]
</beans:value>
</beans:property>
<beans:property name="order" value="0" />
</beans:bean>
Spring MVC et Tiles
serveur applis servlets ctrls definitions tiles
url=ctrl1
appli1
‘/’
select
‘appli1/ctrl1’
servlet1 view1 lay
hea
out
der1
[Link]
foo
.jsp
requete select appli2
p
ter
url=ctrl2 select
me
[Link]
me
p
nu2 nu1.
.jsp jsp
url=ctrl3
view2
reponse
Spring MVC et Tiles
TilesViewResolver
déclaré ds spring-
[Link]
url=ctrl3
view2
reponse
Déclare un composant
/**
* A simple bean that will be injected elsewhere
*/
@Component
public class InjectedBean {
// ..
}
Comment relier les deux
Bibliographie
Chapter 18. Enterprise Java Beans (EJB)
integration
[Link]
ml
[Link]
framework-reference/html/[Link]
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
Déclarer le bean session en tant
que Component Spring declaration du namespace
<?xml version="1.0" encoding="UTF-8"?>
Dans le fichier de configuration
<beans:beans xmlns="[Link]
xmlns:xsi="[Link]
xmlns:beans="[Link] la location de la def du namespace
xmlns:context="[Link]
xmlns:jee="[Link]
xsi:schemaLocation=
"[Link] [Link]
[Link] [Link]
[Link]
[Link]
[Link] [Link]
<jee:remote-slsb
id="myComponent"
jndi-name="java:global/[Link]/[Link]/MyServiceBean"
business-interface="[Link]"/>
</beans:beans>
le nom spring
@Inject
protected MyService injectedBean;
/**
* Simply selects the home view to render by returning its name.
*/
@RequestMapping(value = "/", method = [Link])
public String home(Locale locale, Model model) {
// …
if( injectedBean == null ) {
[Link]("The bean is not injected !.");
return "home";
}
// Injection works !
[Link]("myInjectedBean", injectedBean );
return "success";
}
Accéder à un objet JNDI ou EJB
<jee:jndi-lookup>
Acces par JNDI
<jee:local-slsb>
Acces a un bean local
<jee:remote-slsb>
Acces à un bean distant Ou utiliser @Inject ds le bean
<jee:local-slsb
id="myComponent"
jndi-name="java:global/p1.p2/myBean"
business-interface="[Link]"
/>
Accéder à un objet JNDI ou EJB
Autre méthode
Permet d’utiliser le nom jndi directement dans les
annotations
A tester
<bean
class="[Link]">
<property name="alwaysUseJndiLookup" value="true" />
</bean>
Atelier
ateliers 1
Atelier – Spring et JavaEE
Dependances
<dependency>
<groupId>[Link]</groupId>
<artifactId>hibernate-validator</artifactId>
</dependency>