Support de cours du Framework Spring et Hibernate
…
Qu’est-ce que Spring
Un Framework
Constitué de caractéristiques organisées en 20 modules
Core Container
Fournit les mécanismes :
d’inversion de contrôle
D’injection
De fabrique d’objets (BeanFactory)
Web
Web
Fournit les fonctionalité web de base
Sevlet
Fournit Spring MVC
Permet de séparer le model Domaine et les pages web
Struts
Integration Struts 1. Deprecated (utiliser Struts-Spring integration
Portlet
Pour un environement avec des Portlet
Test
Pour les test avec Junit et TestNG
Scénarios d’utilisation
Scénarios d’utilisation
Custom business logic
can be implemented with simple POJOs
and managed by Spring's IoC container
Transactions
Managed by container (like in EJB container)
Additional services
email and
validation
ORM support
integrated with JPA, Hibernate, JDO and iBatis
Form controllers
Obtenir les librairies
Maven
SPS - Spring Tool Suite
Permet de créer un projet pré-initialisé
org.springframework
spring-context
3.0.0.RELEASE
runtime
com.springsource.repository.maven.release
false
Le cœur de l’environnement Spring est un « conteneur léger »
Un conteneur léger sert à contenir un ensemble d’objets instanciés et initialisés, formant un contexte initial (ou une hiérarchie de contextes) pour une application.
Ce contexte initial est souvent construit à partir d’une description externe (xml) décrivant les objets à créer, les valeurs initiales et les dépendances entre objets.
Les dépendances (liens) entre objets sont automatiquement créées à partir de la description (on parle d’injection de dépendances) et non par les objets eux-mêmes par programmation.
C’est le Design Pattern de l’Inversion du Contrôle : IoC
class Personne { String nom; Voiture car; }
class Voiture {String nom;}
Exemple simplifié:
Avec les classes:
et la description de contexte Spring:
Le contexte initial de l’application dans le conteneur SPRING sera: user
Personne
nom:jean
car:
Voiture
nom:megane
vehicule
Dans le cas de SpringMVC le conteneur va servir à créer:
-Le contexte de l’application Web
-Les objets traitant les requêtes (Controller)
-Les objets créant les pages HTML (View)
-Les objets données des formulaires (Command)
-Les liens avec les couches métiers et BD
-Et pleins d’autres
-Le mapping des URL vers les contrôleurs
-Le mapping des vues , etc.
SpringMVC est un framework de présentation, pour application WEB, suivant le modèle MVC, et fondé sur le conteneur léger de SPRING
L’inversion du contrôle permet ensuite de changer le comportement de l’application, en modifiant la description xml du conteneur, sans
changer les éléments programmés!
Une application 3tier classique:
Une application 3tier avec MVC:
Retour sur le modèle MVC
La org.springframework.web.servlet.DispatcherServlet est le point d’entrée générique qui délègue les requêtes à des Controller
Un org.springframework.web.servlet.mvc.Controller prend en charge une requête, et utilise la couche métier pour y répondre.
Un Controller fabrique un modèle sous la forme d’une java.util.Map contenant les éléments de la réponse.
Un Controller choisit une org.springframework.web.servlet.View qui sera paramétrée par la Map pour donner la page qui sera affichée.
La vision de SpringMVC
Traitement type d’une requête
Pour faire fonctionner Spring MVC,
il faut :
Front Controler
servlet DispatcherServlet
Déclaration dans web.xml
Controllers
Ce sont des POJO annotés @Controller
Des vues
Choix possible de la technologie
Ex: jsp
Un mapping request Controller
Un mapping nom_logique_de_vue => implementation_de_la_vue
Des objets métiers
Objet Spring
Ou Objets JEE
Le « Front Controller »
Il est chargé de traiter les requêtes de l’exterieur
Il analyse l’url, et appelle le contrôleur correspondant
Le contrôleur renvoie un modèle et le nom logique de la page servant à construire la page
Le front contrôleur appelle la page demandée
La page construit la réponse
Le front controlleur renvoie la réponse
Implémentation du Front Controller
C’est un servlet
Déclaré dans META-INF/web.xml
appServlet
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
/WEB-INF/spring/appServlet/servlet-context.xml
1
appServlet
/
Le servlet
Le fichier de configuration de Spring
Le nom et les urls traitées par le servlet
La configuration de Spring
Fichier [servletName]-context.xml
<beans:beans
Indique d’interpreter les annotations
Spécifie le mapping
nom logique => vues
Chemin des classes
annotées a scanner
Controller simple
@Controller
public class GreetingController {
@RequestMapping("/greeting")
public String greeting(
@RequestParam(value="name", required=false, defaultValue="World") String name,
Model model) {
model.addAttribute("name", name);
return "greeting";
}
}
Déclare un contrôleur
L’url associée a ce ctrl
Mapping paramètre => argument
Le model qui sera passé à la page
Nom logique de la page
Un attribut qui sera passé à la page
Controller
/**
* Simply selects the home view to render by returning its name.
*/
@RequestMapping(value = "/", method = RequestMethod.GET)
public String home(Locale locale, Model model) {
logger.info("Welcome home! The client locale is {}.", locale);
Date date = new Date();
DateFormat dateFormat =
DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
String formattedDate = dateFormat.format(date);
model.addAttribute("serverTime", formattedDate );
return "home";
}
Spécifie le type de requete
Demande l’objet Locale
Controller
Peut contenir plusieurs méthodes avec differentes 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 methodes sont alors relative a l’url de la classe.
Technologies supportées
Spring permet différente technologie pour les vues:
Struts, Tiles
Tapestry
JSP
Spring et JSP
JSF sert de template à la réponse renvoyé par le frontcontrolleur
Les données viennent des modèles renvoyé par le controlleur
<%@ page session="false" %>
Getting Started: Serving Web Content
Hello again ${name} !
Remplacé par la valeur trouvé dans le modèle
Mapping nom logique => vues
Les vues sont séparées des contrôleurs
Un controleur specifie la vue qui doit être utilisé
Il peut envoyer une vue differente en fonction du résultat
(ok, cancel, …)
Un mapper se charge de mapper les noms logique vers
les noms physique
Déclaré dans le fichier de config [nom]_config.xml
Ex:
Où placer les vues ?
Dans un répertoire sous
WEB-INF
L’entéte
views/contact.jsp
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
Spring 3 MVC Series - Contact Manager
…
Le form
First Name
Last Name
Telephone
L’url où la requête est envoyée
Le nom d’un attribut dans l’objet ‘command’
Le contrôleur
@Controller
@SessionAttributes
public class ContactController {
@RequestMapping(value = "/addContact.html", method = RequestMethod.POST)
public String addContact(@ModelAttribute("contact")
Contact contact, BindingResult result, Model model) {
System.out.println("First Name:" + contact.getFirstname() +
"Last Name:" + contact.getLastname());
contact.setEmail(contact.getFirstname() + "." + contact.getLastname());
model.addAttribute("command", contact);
return "contact";
// return "redirect:contacts.html";
}
@RequestMapping("/contacts.html")
public ModelAndView showContacts() {
return new ModelAndView("contact", "command", new Contact("name", "lastname"));
}
}
L’url où la requête est envoyée
L’url où la requête est envoyée
Pour connaitre les erreurs lors du Bind
On peut demander des redirection vers une URL
L’objet passé entre le ctrl et le form
Classe POJO
public class Contact {
private String firstname;
private String lastname;
private String email;
private String telephone;
// Getter and setters …
}
@ModelAttribute sur les parametres
An @ModelAttribute on a method argument indicates the argument should be retrieved from the model.
If not present in the model, the argument should be instantiated first and then added to the model.
Once present in the model, the argument’s fields should be populated from all request parameters that have matching names.
This is known as data binding in Spring MVC, a very useful mechanism that saves you from having to parse each form field individually.
Comment initialiser un objet dans le model
/**
* Initialize attribute in the model.
* Use default name 'contact' (name of the returned type).
public Contact initContact() {
Contact contact = new Contact();
contact.setFirstname("set firstname");
contact.setLastname("set lastname");
return contact;
}
Doc chap 22
Accéder à un objet JNDI ou EJB
L’objet doit exister dans un autre container
On injecte le bean
ex: injecter un bean dans Spring membres-servlet.xml
…
cache="true" />
injection
recherche du bean – lien nom logique nom JNDI
Accéder à un objet JNDI ou EJB
Acces par JNDI
Acces a un bean local
Acces à un bean distant
business-interface="com.mycom.MyComponent"/>
Accéder à un objet JNDI ou EJB
Autre methode
Permet d’utiliser le nom jndi directement dans les annotations
A tester
<bean
class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor">
Spring fournit la notion de composant
On peut injecter des composants dans d’autre composant
Même principe que JEE
public class MovieRecommender {
private ApplicationContext context;
public MovieRecommender() {
}
// ...
}
Plugins Eclipse pour le développement avec Spring
all-in-one distribution
Update zip
Update site (pour ajouter dans une application existante).
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
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
Convertir un projet ‘boot ’ en war
jar-to-war/
Modifier le build.gradle
Ajouter apply plugin: ' war‘
Modifier jar en war
Ajouter la classe
HelloWebXml extends
SpringBootServletInitializer
./gradlew clean build
Vous obtenez un war
Déployer le war dans votre serveur
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'spring-boot'
apply plugin: 'war'
war {
baseName =
'gs-serving-web-content'
version = '0.1.0'
}
hello/HelloWebXml.java
package hello;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.SpringBootServletInitializer;
public class HelloWebXml extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder
configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
}
Créer un nouveau projet
New ->Other->Spring->Spring Project
Choisir Spring MVC Project
Utiliser le même nom pour le nom de projet et le ‘top level package’
Nouveau projet
Ce projet peut être compilé sous Eclipse.
Il peut être déployé dans Glassfish
Spring MVC
Gradle
Outils similaire a Maven
Chaque exemple de Spring vient avec un bin permettant de lancer gradle
ouvrir une console
./gradlew clean build
Charge les jar gradle
Execute build.gradle