Programmation Web Avancée Spring MVC, Injection de

publicité
Programmation Web Avancée 4 : Plan
Programmation Web Avancée
Spring MVC, Injection de
Dépendances
MVC Web et Spring MVC
Projets
Rappel : MVC Web en Pratique
Injection de Dépendances
Introduction à la persistance en Java
Java Persistence API (JPA)
4 / 40 − Rémi Emonet − Programmation Web Avancée Spring MVC, Injection de Dépendances
Programmation Web Avancée 4 : Plan
MVC Web et Spring MVC
MVC avec Spring dans ce cours
Modèle
JavaBeans (objets Java)
persistance avec JPA et Repositories de Spring Data
Projets
Rappel : MVC Web en Pratique
Contrôleur
description de route : annotations Java
méthodes Java, avec injection de paramètres
classe Model pour le ViewModel
Injection de Dépendances
Introduction à la persistance en Java
Vue
Java Persistence API (JPA)
templates Thymeleaf
accès automatique au ViewModel
5 / 40 − Rémi Emonet − Programmation Web Avancée Spring MVC, Injection de Dépendances
6 / 40 − Rémi Emonet − Programmation Web Avancée Spring MVC, Injection de Dépendances
Interaction Client Serveur et MVC
Programmation Web Avancée 4 : Plan
MVC Web et Spring MVC
Projets
0
GET ...?q=jean%20dujardin
Router
(contrôleur)
Injection de Dépendances
contenu HTML
1
7
Contrôleur
Légende:
- 0, 1 : requête HTTP
- 2 : interogation du modèle
- 3/4 : communication avec la base de donnée ou l'ORM
- 5 : envoi du ViewModel (modèle de vue)
- 6 : vue rendue (HTML, JSON, ...)
- 7 : réponse HTTP
2
Rappel : MVC Web en Pratique
Introduction à la persistance en Java
6
5
Vue
Java Persistence API (JPA)
4
Repository
Services
(modèle)
DB
3
7 / 40 − Rémi Emonet − Programmation Web Avancée Spring MVC, Injection de Dépendances
8 / 40 − Rémi Emonet − Programmation Web Avancée Spring MVC, Injection de Dépendances
Les Projets
But
faire une application web
avec génération de page en coté serveur
avec serveur REST + client ReactJS
Organisation
équipes de 3 personnes
composition des équipes pour lundi (10 oct.)
soutenances le 2 décembre
Conseils
choisir/proposer son sujet
commencer tout de suite (partie que serveur)
utiliser git
Git : installer git avant vendredi
(pour windows, voir le lien sur le
guide DSC)
Détails sur le site, projets
9 / 40 − Rémi Emonet − Programmation Web Avancée Spring MVC, Injection de Dépendances
Programmation Web Avancée 4 : Plan
MVC Web et Spring MVC
Projets
10 / 40 − Rémi Emonet − Programmation Web Avancée Spring MVC, Injection de Dépendances
Previously in PWA (+ astuces)
Un modèle « beurk »
des équipes avec des co-équipiers
sous forme d'objets Java dans une variable « globale »
Un/des contrôleur(s)
Rappel : MVC Web en Pratique
Injection de Dépendances
Introduction à la persistance en Java
Java Persistence API (JPA)
annotation de classe @Controller
annotation de méthode @RequestMapping(.....)
paramètre « magique » Model m , qui sera passé à la vue
m.addAttribute("letruc", valeur) pour remplir le « modèle de vue »
paramètre et annotation @RequestParameter pour les formulaires
capture de pattern dans l'url avec @PathVariable
Une/des vue(s)
fichiers Thymeleaf = XHTML + th:.... (templates dite naturelles)
remplacer le contenu d'une balise, attribut ... th:text="${letruc}"
...
accès à une propriété d'un objet ${letruc.machin} équivalent à letruc.getMachin() en
Java
répéter la balise donnée, attribut ... th:each="e : ${letruc}"
mélanger texte et variables dans une balise
la balise doit avoir th:inline="text" (ou il faut utiliser Thymeleaf 3)
dans la balise, utiliser des doubles crochets, e.g., Bonjour [[${nom}]] !
gérer les formulaires (cf TP) avec th:action , th:object , th:field
Convention maven (système de build) + Spring
fichiers Java dans src/main/java/.....
fichiers templates dans src/main/resources/templates/
fichiers statiques dans src/main/resources/static/ (pour les .css, .js, images etc)
11 / 40 − Rémi Emonet − Programmation Web Avancée Spring MVC, Injection de Dépendances
12 / 40 − Rémi Emonet − Programmation Web Avancée Spring MVC, Injection de Dépendances
Fait entre temps : ajout d'un "id"
aux classe du modèle (Equipe et
Personne)
th:inline="text" , lien
détails ( th:href="@{....}" )
13 / 40 − Rémi Emonet − Programmation Web Avancée Spring MVC, Injection de Dépendances
14 / 40 − Rémi Emonet − Programmation Web Avancée Spring MVC, Injection de Dépendances
suppression, @RequestParam ,
return "redirect:/....";
page de détails @PathVariable
15 / 40 − Rémi Emonet − Programmation Web Avancée Spring MVC, Injection de Dépendances
16 / 40 − Rémi Emonet − Programmation Web Avancée Spring MVC, Injection de Dépendances
Programmation Web Avancée 4 : Plan
MVC Web et Spring MVC
Projets
Rappel : MVC Web en Pratique
formulaire d'ajout avec
th:action (et th:object ,
th:field , et constructeur vide)
17 / 40 − Rémi Emonet − Programmation Web Avancée Spring MVC, Injection de Dépendances
Injection de Dépendances
Introduction à la persistance en Java
Java Persistence API (JPA)
18 / 40 − Rémi Emonet − Programmation Web Avancée Spring MVC, Injection de Dépendances
Injection de dépendance (DI)
Cas sans injection de dépendance
il nous faut une instance (par ex, une connection DB)
on la crée (ou on utilise une « Factory »)
Patron « injection de dépendance »
Dependency Injection (DI) Inversion of Control (IoC)
quelqu'un fourni l'instance (e.g. avec @Component ), qui est
injectée dans notre programme
injection par constructeur ou par “setter”
1
2
3
4
class UserObject {
@Inject Connection connection;
@Inject BlablaService blabla;
}
Ce que fait à peu près le framework d'injection : il cherche des
implémentations de Connection et BlablaService, puis
1
2
3
4
5
Injectons avec @Inject et
@Component (+ ajout de
dépendance maven à
javax.inject)
Connection cDB = new SQLDataConnection();
BlablaService s = new BlaBlaServiceImpl();
UserObject obj = new UserObject();
obj.setConnection(cDB);
obj.setService(s);
19 / 40 − Rémi Emonet − Programmation Web Avancée Spring MVC, Injection de Dépendances
20 / 40 − Rémi Emonet − Programmation Web Avancée Spring MVC, Injection de Dépendances
Programmation Web Avancée 4 : Plan
MVC Web et Spring MVC
Persistence: motivation
When we close/restart an application
memory is freed
all objects are lost
Projets
Rappel : MVC Web en Pratique
Injection de Dépendances
Introduction à la persistance en Java
Persistence
saving objects state
... on a permanent storage (non-volatile), e.g., database, file, etc
allows for reloading objects later
Java Persistence API (JPA)
21 / 40 − Rémi Emonet − Programmation Web Avancée Spring MVC, Injection de Dépendances
Persistence Options in Java
Simple JDBC with or without DAOs (DataAccessObjects)
direct access to the SQL database
DAO: object that encapsulates/hides SQL requests
ORM Concept: Object-Relational Mapping
systematic mapping between Java objects and database
relations/tables
Persistence Frameworks with ORM
JPA (Java Persistence API)
JDO (Java Data Objects)
EJB 3 (Entreprise JavaBeans)
Hibernate (Spring), via JPA
23 / 40 − Rémi Emonet − Programmation Web Avancée Spring MVC, Injection de Dépendances
22 / 40 − Rémi Emonet − Programmation Web Avancée Spring MVC, Injection de Dépendances
Simple JDBC Example
1 import java.sql.*;
2 …
3 // JDBC driver name and database URL
4 static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
5 static final String DB_URL = "jdbc:mysql://localhost/EMP";
6 // Database credentials
7 static final String USER = "username";
8 static final String PASS = "password";
9
10 public static void main(String[] args) throws ... {
11
12
Class.forName(JDBC_DRIVER);
13
14
Connection conn = DriverManager.getConnection(DB_URL, USER, PASS);
15
16
Statement stmt = conn.createStatement();
17
18
ResultSet rs = stmt.executeQuery("SELECT id, prenom, nom, age FROM
Employes");
19
20
while(rs.next()){
21
22
int id = rs.getInt("id");
23
int age = rs.getInt("age");
24
String first = rs.getString("prenom");
25
String last = rs.getString("nom");
26
27
System.out.print(id + " : " + first + " " + last + " agé de " + age);
28
}
29
30
rs.close();
// hum....
31
stmt.close(); // hum....
32
conn.close(); // hum....
33 }
34 …
24 / 40 − Rémi Emonet − Programmation Web Avancée Spring MVC, Injection de Dépendances
Simple JDBC example, Java 7+
1 import java.sql.*;
2 …
3 // JDBC driver name and database URL
4 static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
5 static final String DB_URL = "jdbc:mysql://localhost/EMP";
6 // Database credentials
7 static final String USER = "username";
8 static final String PASS = "password";
9
10 public static void main(String[] args) throws ... {
11
12
Class.forName(JDBC_DRIVER);
13
14
try (
15
Connection conn = DriverManager.getConnection(DB_URL, USER, PASS);
16
Statement stmt = conn.createStatement();
17
ResultSet rs = stmt.executeQuery("SELECT id, prenom, nom, age FROM
Employes");
18
) {
19
20
while(rs.next()){
21
22
int id = rs.getInt("id");
23
int age = rs.getInt("age");
24
String first = rs.getString("prenom");
25
String last = rs.getString("nom");
26
27
System.out.print(id + " : " + first + " " + last + " agé de " +
age);
28
}
29
}
30 }
25 / 40 − Rémi Emonet − Programmation Web Avancée Spring MVC, Injection de Dépendances
JDBC simple :
avantages/inconvénients ?
26 / 40 − Rémi Emonet − Programmation Web Avancée Spring MVC, Injection de Dépendances
Objet-Relational Mapping: concept
Object-Relational Mapping
Relation(s)
Car
id: long
price: long
model: String
company: String
Questions?
what class corresponds to what table
what attribute corresponds to what column
what attribute corresponds to what foreign key
what are the multiplicities
Vehicle
id
company
model
price
opt_id
In practice
using JDBC, manually… tedious
source code very long (most of the app)
very repetitive code
dangerous code (error-prone)
difficult to evolve
Option
*
id: long
desc: String
Option
id
using a persistence framework
desc
JPA, JDO, Hibernate
writing metadata on Java classes and attributes
Objects
27 / 40 − Rémi Emonet − Programmation Web Avancée Spring MVC, Injection de Dépendances
28 / 40 − Rémi Emonet − Programmation Web Avancée Spring MVC, Injection de Dépendances
Programmation Web Avancée 4 : Plan
JPA: Java Persistance API
MVC Web et Spring MVC
Why the JPA standard?
Pure JDBC: tedious
Data Access Objects: abstraction, but too much code
need a Object/Relational Mapping (ORM) description
XML description too verbose and not DRY (Don't Repeat Yourself)
proliferation of frameworks (hibernate, toplink, ...)
need a usable standard
Projets
Rappel : MVC Web en Pratique
Injection de Dépendances
Introduction à la persistance en Java
Java Persistence API (JPA)
What is JPA?
a set of annotations and conventions
description of object/relational mappings
originally, a part EJB 3 (Entreprise Java Beans)
an EntityManager to manage data (transparent in Spring)
to save, em.persist()
to delete, em.remove()
to read, em.find() , …
29 / 40 − Rémi Emonet − Programmation Web Avancée Spring MVC, Injection de Dépendances
30 / 40 − Rémi Emonet − Programmation Web Avancée Spring MVC, Injection de Dépendances
JPA Annotations: simple example
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import
import
import
import
javax.persistence.Column;
javax.persistence.Entity;
javax.persistence.Id;
javax.persistence.GeneratedValue;
@Entity
public class Car {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private String company;
private String model;
private long price;
}
...constr/get/set... Important!
31 / 40 − Rémi Emonet − Programmation Web Avancée Spring MVC, Injection de Dépendances
JPA Annotations: simple example
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import
import
import
import
import
javax.persistence.Column;
javax.persistence.Entity;
javax.persistence.Id;
javax.persistence.GeneratedValue;
javax.persistence.Table;
@Entity
@Table(name = "Vehicle")
public class Car {
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@Column(name = "company")
private String company;
@Column(name = "model")
private String model;
@Column(name = "price")
private long price;
}
...constr/get/set... Important!
32 / 40 − Rémi Emonet − Programmation Web Avancée Spring MVC, Injection de Dépendances
JPA Annotations
Class-level
@Entity
@Table
(EJB @Stateless)
(EJB @Stateful)
…
Attribute-level, JavaBean
@Column
@Id
@GeneratedValue
@Temporal, @Lob, @Basic
@Version
@Transient
…
Others
@PersistenceContext
…
Manipulating JPA Entities
(Using an EntityManager )
to read, em.find() , …
to save, em.persist()
to delete, em.remove()
Using Repositories
Attribute-level, JavaBean
relations
@OneToOne
@ManyToOne
@OneToMany
@ManyToMany
@MapKey
@OrderBy
…
33 / 40 − Rémi Emonet − Programmation Web Avancée Spring MVC, Injection de Dépendances
abstraction to list and filter objects
need to define an interface
implemented automatically, e.g., by Spring Data
interfaces: Repository, CrudRepository,
PagingAndSortingRepository
implementation is obtained via dependency injection
34 / 40 − Rémi Emonet − Programmation Web Avancée Spring MVC, Injection de Dépendances
What Did We Just Do?
Update the model
add an @Entity on the class
add a long id field,
with @Id @GeneratedValue(strategy=GenerationType.AUTO)
JPA ( @Entity , @Id ,
@OneToMany , ...), Spring Data
( CrudRepository x2 + .save ),
/TEST
Create a new repository
an (empty) interface (not a class)
extending CrudRepository<MyEntity, Long>
Used the new repository interface
injected it
used findAll and save
the implementation being provided by spring data
According to project configuration (and defaults)
spring automatically uses an H2 database
the database is in memory (by default)
the database schema is automatically created
the database is dropped at startup
35 / 40 − Rémi Emonet − Programmation Web Avancée Spring MVC, Injection de Dépendances
36 / 40 − Rémi Emonet − Programmation Web Avancée Spring MVC, Injection de Dépendances
What Did We Just Do?
Changing project configuration
to override default configuration
adding key=value properties in application.properties
Using a file database (instead of solely in-memory)
spring.datasource.url=jdbc:h2:/tmp/mytestdb
Keeping Our Data!
Tuning application.properties
Stopped dropping (and recreating) the database everytime
spring.jpa.hibernate.ddl-auto=none
NB about previous point
in case one need to re-create the databse (schema update)
the line can be remove
or, use spring.jpa.hibernate.ddl-auto=create-drop
Some properties
spring.datasource.password ,
spring.datasource.username
server.port
and WAY more
37 / 40 − Rémi Emonet − Programmation Web Avancée Spring MVC, Injection de Dépendances
38 / 40 − Rémi Emonet − Programmation Web Avancée Spring MVC, Injection de Dépendances
Points Clés
ORM : avantages/inconvénients
?
39 / 40 − Rémi Emonet − Programmation Web Avancée Spring MVC, Injection de Dépendances
40 / 40 − Rémi Emonet − Programmation Web Avancée Spring MVC, Injection de Dépendances
Téléchargement