45
Spring MVC Cedric Dumoulin

Cedric Dumoulin. Plan Bibliographie Injecter des composants Spring et JEE Header Footer et Body Internationalization Validation Gestion des erreurs

Embed Size (px)

Citation preview

  • Page 1
  • Cedric Dumoulin
  • Page 2
  • Plan Bibliographie Injecter des composants Spring et JEE Header Footer et Body Internationalization Validation Gestion des erreurs
  • Page 3
  • Bibliographie Spring Framework http://docs.spring.io/spring/docs/3.2.5.RELEASE/spring -framework-reference/htmlsingle/#overview http://docs.spring.io/spring/docs/3.2.5.RELEASE/spring -framework-reference/htmlsingle/#overview Designing and Implementing a Web Application with Spring http://spring.io/guides/tutorials/web/
  • Page 4
  • 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 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
  • Page 5
  • Bibliographie Spring 3.x tutorials http://www.roseindia.net/spring/spring3/index.shtml http://yannart.developpez.com/java/spring/tutoriel/ http://www.theserverside.com/tutorial/Spring-30- Tutorial-Setting-Up-Configuring-The-Environment http://www.theserverside.com/tutorial/Spring-30- Tutorial-Setting-Up-Configuring-The-Environment
  • Page 6
  • Guides Accessing Data with JPA http://spring.io/guides/gs/accessing-data-jpa/ Designing and Implementing a Web Application with Spring http://spring.io/guides/tutorials/web/
  • Page 7
  • Page 8
  • Spring fournit la notion de composant On peut injecter des composants dans dautre composant Mme principe que JEE Declarer un composant: @Component, @Named Injecter un composant: @Inject, @Autowired
  • Page 9
  • Dclarer un composant Par dfaut, le nom est le nom simple de la classe (commenant par une minuscule) 2 tags quivalent: @Component et @Named On peut spcifier 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.. } /** * A simple bean that will be injected elsewhere */ @Component public class InjectedBean { private String firstname = "John"; private String lastname = "Doe"; //.. Getter an setter.. } Dclare un composant
  • Page 10
  • Injecter un composant @Inject Peut se faire sur un attribut, un setter, On peut spcifier le nom @Inject("injectedComponent") @Controller public class HomeController { /** * Try to inject a bean */ @Inject protected InjectedBean injectedBean; //.. } @Controller public class HomeController { /** * Try to inject a bean */ @Inject protected InjectedBean injectedBean; //.. } Spring injecte le bean du bon type
  • Page 11
  • Page 12
  • Webographie 22.2 Accessing EJBs http://docs.spring.io/spring/docs/4.0.0.BUILD- SNAPSHOT/spring-framework- reference/htmlsingle/#ejb http://docs.spring.io/spring/docs/4.0.0.BUILD- SNAPSHOT/spring-framework- reference/htmlsingle/#ejb
  • Page 13
  • Injecter des EJB Session dans Spring Cest possible ! En deux temps: dclarer le bean Session en tant que Component Spring injecter le component Spring
  • Page 14 declaration du namespace la location de la def du namespace le nom jndi est affich par le serveur dans ses logs le nom spring linterface du bean JEE">
  • Dclarer le bean session en tant que Component Dans le fichier de configuration declaration du namespace la location de la def du namespace le nom jndi est affich par le serveur dans ses logs le nom spring linterface du bean JEE
  • Page 15
  • Injecter le bean Methode classique @Controller public class HomeController { @Inject protected MyService 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"; } @Controller public class HomeController { @Inject protected MyService 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"; }
  • Page 16 ">
  • Accder un objet JNDI ou EJB Acces par JNDI Acces a un bean local Acces un bean distant
  • Page 17 ">
  • Accder un objet JNDI ou EJB Autre methode Permet dutiliser le nom jndi directement dans les annotations A tester
  • Page 18
  • Page 19
  • Tous les sites proposent des pages cohrentes Avec un header, un footer, un body, un menu Faut-il coder ces lments 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
  • Page 20
  • Principe Dfinir 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 + partie commune Vous dfinissez le body Le framework ce charge de construire la page en assemblant les parties pour vous
  • Page 21
  • Webographie Spring 3 MVC: Tiles Plugin Tutorial with Example in Eclipse http://viralpatel.net/blogs/spring-3-mvc-tiles-plugin- tutorial-example-eclipse/ http://viralpatel.net/blogs/spring-3-mvc-tiles-plugin- tutorial-example-eclipse/ Tiles https://tiles.apache.org/
  • Page 22
  • Page 23
  • Webographie http://viralpatel.net/blogs/spring-3-mvc- internationalization-i18n-localization-tutorial- example/
  • Page 24
  • Principe Utilise la notion de Locale Pays_langue FR_fr, US_en Dans le code, on utilise des constantes la place du texte Les constantes sont dfinies dans des fichiers Pair nom=valeur Un fichier par langue Un fichier par dfaut Tous les fichiers ont le mme nom Mais des extensions en fonction du locale: messages.properties messages_FR_fr.properties
  • Page 25
  • Alternatives: Des pages diffrentes en fonction du locale Possible avec Tiles
  • Page 26
  • Spring MVC Les fichiers properties Permet dutiliser des constantes dans les pages Les dfinitions sont dans des fichiers.properties fichier par dfaut fichier local = fr pas dfinit = venant du fichier par dfaut
  • Page 27
  • La dclaration dans la page ${serverTime}. ${serverTime}. La taglib utilise Le message
  • Page 28 ">
  • La configuration Dans le fichier de configuration Spring [servlet]-config.xml Spcifier que lon veut utiliser les messages de properties
  • Page 29
  • Atelier Crer un nouveau projet Spring. Spring gnre une page home . Internationaliser cette page.
  • Page 30
  • Laisser lutilisateur choisir sa langue Il faut ajouter un choix du local Il faut prendre en compte le changement voir tuto http://viralpatel.net/blogs/spring-3-mvc- internationalization-i18n-localization-tutorial-example/
  • Page 31
  • Page 32
  • Documentation http://docs.spring.io/spring/docs/3.2.5.RELEASE/spri ng-framework-reference/htmlsingle/#validation http://docs.spring.io/spring/docs/3.2.5.RELEASE/spri ng-framework-reference/htmlsingle/#validation 7.8.4 Spring MVC 3 Validation
  • Page 33
  • Que valider ? Il faut valider pour se garantir : De mauvaises saisies dans les formulaires De donnes saisies non valables pour le mtier Les mauvaises saisies peuvent tre dtects par: la conversion de la requte http objet command Les contraintes mtiers peuvent tre dtects par: des objets de validation Spring 3.x
  • Page 34
  • Erreur de conversion @ModelAttribute permet de rcuprer lobjet command. Il est peupl partir de la requete, donc avec les valeurs saisies dans le formulaire. Il y a conversion implicite String -> type dans lobjet commande Il peut y avoir plusieur s @ModelAttribute BindingResult result contient les ventuelles erreurs de conversion doit tre plac immdiatement aprs le @ModelAttribute auquel il se rfere @RequestMapping(method = RequestMethod.POST) protected String onSubmit( @ModelAttribute("commandAjout") CommandAjout commandAjout, BindingResult result, SessionStatus status ) throws Exception { if( result.hasErrors()) { return "formulaire"; } groupe.addMembre(commandAjout.getNouveauMembre()); status.setComplete(); return "confirmation"; } @RequestMapping(method = RequestMethod.POST) protected String onSubmit( @ModelAttribute("commandAjout") CommandAjout commandAjout, BindingResult result, SessionStatus status ) throws Exception { if( result.hasErrors()) { return "formulaire"; } groupe.addMembre(commandAjout.getNouveauMembre()); status.setComplete(); return "confirmation"; } retourne au formulaire en cas derreurs efface la session si ok Spring 3.x
  • Page 35
  • Validation Action de valider des donnes en fonction du mtier ex: 00"); } else if (p.getAge() > 110) { e.rejectValue("age", "too.darn.old", "Age seem too old"); } (attributeName, errorCode, defaultMsg) errorCode i18n (attributeName, errorCode, defaultMsg) errorCode i18n">
  • Exemple de Validator public class ContactValidator implements Validator { /* * This Validator validates *just Contact instances */ public boolean supports(Class clazz) { return Contact.class.equals(clazz); } public void validate(Object obj, Errors e) { ValidationUtils.rejectIfEmptyOrWhitespace(e, "firstname", "firstname.empty", "First Name is required"); ValidationUtils.rejectIfEmptyOrWhitespace(e, "lastname", "lastname.empty", "Last Name is required"); Contact p = (Contact) obj; if (p.getAge() < 0) { e.rejectValue("age", "negativevalue", "Age should be >0"); } else if (p.getAge() > 110) { e.rejectValue("age", "too.darn.old", "Age seem too old"); } public class ContactValidator implements Validator { /* * This Validator validates *just Contact instances */ public boolean supports(Class clazz) { return Contact.class.equals(clazz); } public void validate(Object obj, Errors e) { ValidationUtils.rejectIfEmptyOrWhitespace(e, "firstname", "firstname.empty", "First Name is required"); ValidationUtils.rejectIfEmptyOrWhitespace(e, "lastname", "lastname.empty", "Last Name is required"); Contact p = (Contact) obj; if (p.getAge() < 0) { e.rejectValue("age", "negativevalue", "Age should be >0"); } else if (p.getAge() > 110) { e.rejectValue("age", "too.darn.old", "Age seem too old"); } (attributeName, errorCode, defaultMsg) errorCode i18n (attributeName, errorCode, defaultMsg) errorCode i18n
  • Page 38
  • Spring et @Valid Prparation Annotation JSR-303 ncessite validation-api.jar Peut tre utilis avec Spring MVC ncessite de dclarer les validators (dans le controller par exemple) /** * Register a validator that will be lookup when a parameter is binded to a handler * argument (with @ModelAttribute() for example). * @param binder */ @InitBinder protected void initBinder(WebDataBinder binder) { // register the ContactValidator used to validate objects of type Contact. binder.setValidator(new ContactValidator() ); } /** * Register a validator that will be lookup when a parameter is binded to a handler * argument (with @ModelAttribute() for example). * @param binder */ @InitBinder protected void initBinder(WebDataBinder binder) { // register the ContactValidator used to validate objects of type Contact. binder.setValidator(new ContactValidator() ); }
  • Page 39
  • Spring et @Valid Utilisation /** Handler called when theform is submitted. * The @Valid annotation is used to validate the input model. Spring lookup for a * validator accepting the class. */ @RequestMapping(value = "/addContact.html", method = RequestMethod.POST) public String addContact(@Valid @ModelAttribute("command") Contact contact, BindingResult result, Model model) { // Check the binding results. Binding and validations errors are contained // in the BindingResult object. // If there is some binding or validation errors, stop and return // to the form. if( result.hasErrors()) { System.err.println("errors encountered !!"); return "contact"; } } /** Handler called when theform is submitted. * The @Valid annotation is used to validate the input model. Spring lookup for a * validator accepting the class. */ @RequestMapping(value = "/addContact.html", method = RequestMethod.POST) public String addContact(@Valid @ModelAttribute("command") Contact contact, BindingResult result, Model model) { // Check the binding results. Binding and validations errors are contained // in the BindingResult object. // If there is some binding or validation errors, stop and return // to the form. if( result.hasErrors()) { System.err.println("errors encountered !!"); return "contact"; } } Un validator pour ce type doit tre accessible !
  • Page 40
  • JSR-303 Bean validation API Annotation JSR-303 ncessite validation-api.jar Ncessite une implmentation du standard ! Les contraintes de validation sont directement dans lobjet valider Voir doc Spring
  • Page 41
  • Page 42
  • Documentation 18.2 JSP & JSTL http://docs.spring.io/spring/docs/4.0.0.BUILD- SNAPSHOT/spring-framework- reference/htmlsingle/#view-jsp http://docs.spring.io/spring/docs/4.0.0.BUILD- SNAPSHOT/spring-framework- reference/htmlsingle/#view-jsp
  • Page 43
  • Comment afficher les erreurs dans la page ? Spring renvoie lobjet Errors dans la rponse Cet objet contient toutes les erreurs Chaque erreur est identifies par un id le nom de la proprit en gnral Le tag utilise cet objet pour afficher des messages On indique lid de lerreur vrifier le nom de la proprit en gnral
  • Page 44 0"); } else if (p.getAge() > 110) { e.rejectValue("age", "too.darn.old", "Age seem too old"); } public class ContactValidator implements Validator { /* * This Validator validates *just Contact instances */ public boolean supports(Class clazz) { return Contact.class.equals(clazz); } public void validate(Object obj, Errors e) { ValidationUtils.rejectIfEmptyOrWhitespace(e, "firstname", "firstname.empty", "First Name is required"); ValidationUtils.rejectIfEmptyOrWhitespace(e, "lastname", "lastname.empty", "Last Name is required"); Contact p = (Contact) obj; if (p.getAge() < 0) { e.rejectValue("age", "negativevalue", "Age should be >0"); } else if (p.getAge() > 110) { e.rejectValue("age", "too.darn.old", "Age seem too old"); } (attributeName, errorCode, defaultMsg) errorCode i18n (attributeName, errorCode, defaultMsg) errorCode i18n">
  • Lobjet Error est remplie par le Validator public class ContactValidator implements Validator { /* * This Validator validates *just Contact instances */ public boolean supports(Class clazz) { return Contact.class.equals(clazz); } public void validate(Object obj, Errors e) { ValidationUtils.rejectIfEmptyOrWhitespace(e, "firstname", "firstname.empty", "First Name is required"); ValidationUtils.rejectIfEmptyOrWhitespace(e, "lastname", "lastname.empty", "Last Name is required"); Contact p = (Contact) obj; if (p.getAge() < 0) { e.rejectValue("age", "negativevalue", "Age should be >0"); } else if (p.getAge() > 110) { e.rejectValue("age", "too.darn.old", "Age seem too old"); } public class ContactValidator implements Validator { /* * This Validator validates *just Contact instances */ public boolean supports(Class clazz) { return Contact.class.equals(clazz); } public void validate(Object obj, Errors e) { ValidationUtils.rejectIfEmptyOrWhitespace(e, "firstname", "firstname.empty", "First Name is required"); ValidationUtils.rejectIfEmptyOrWhitespace(e, "lastname", "lastname.empty", "Last Name is required"); Contact p = (Contact) obj; if (p.getAge() < 0) { e.rejectValue("age", "negativevalue", "Age should be >0"); } else if (p.getAge() > 110) { e.rejectValue("age", "too.darn.old", "Age seem too old"); } (attributeName, errorCode, defaultMsg) errorCode i18n (attributeName, errorCode, defaultMsg) errorCode i18n
  • Page 45
  • Le dclare o doivent tre plac les messages derreurs Spring 3 MVC Series - Contact Manager Contact Manager First Name Last Name Spring 3 MVC Series - Contact Manager Contact Manager First Name Last Name Affich uniquement si lerreur existe !