Struts 2
Transcription
Struts 2
Applications Web STRUTS 2 Framework(s) STRUTS Cours IHM Frédéric MOAL Université d’Orléans Master 1ère année année 2012/2013 1 2 1 Struts 2 Ressources “Fusion” de deux frameworks : WebWork 2, avec Struts. But : simplifier les développement. Le site officiel : – http://struts.apache.org/ – lib : liste des librairies – apps : exemples d’application (vide) Struts version 2, http://struts.apache.org/2.3.4.1/ Tutoriaux developpez.com – http://tahe.developpez.com/ Livre « Struts 2 in action » par Donald Brown - Chad Michael Davis - Scott Stanlick aux éditions Manning Différences importantes entre Struts 1 et Struts 2 3 4 2 Struts 2 : Architecture Struts 2 : extensible par Plugins 5 6 3 De Struts 1 à Struts 2 … Struts 1 Action ActionForm ActionForward struts-config.xml ActionServlet RequestProcessor Le modèle MVC de Struts 2 Struts 2 Action Action or POJO’s Result struts.xml FilterDispatcher Interceptors 7 8 4 MVC de Struts 2 : configuration MVC de Struts 2 : configuration Servlet contrôleur, dans web.xml : URLs demandées de la forme http://machine:port/contexte/rep1/rep2/.../Action Définitions des URLs acceptées dans fichier XML : <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/javaee"…version="2.5"> Exemple : <filter> <filter-name>struts2</filter-name> <filter-class> org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app> <package name="actions" namespace="/actions" extends="struts-default"> <action name="Action1" class="actions.Action1"> <result name="page1">/vues/Page1.jsp</result> <result name="page2">/vues/Page2.jsp</result> </action> </package> Pour http://machine:port/contexte/actions/Action1 9 10 5 MVC de Struts 2 : fonctionnement MVC de Struts 2 : fonctionnement 1. Demande "http://machine:port/contexte/actions/Action1" 2. Traitement : a. le contrôleur C consulte son fichier de configuration et vérifie que b. c. l'action actions/Action1 existe (namespace + name) le contrôleur C instancie [2a] une classe de type [actions.Action1] Le nom et le package de cette classe peuvent être quelconques si l'Url a des paramètres [param1=val1¶m2=val2&...], le contrôleur C affecte ces paramètres à la classe [actions.Action1] : [actions.Action1].setParami(valeuri) => la classe [actions.Action1] doit avoir ces méthodes setParami pour chacun des paramètres parami attendus d. le contrôleur C demande à la méthode [String execute()] de la classe [actions.Action1] de s'exécuter : elle a accès aux paramètres parami, et peut avoir besoin de la couche [metier] [2b]. Une fois la demande du client traitée, celle-ci peut appeler diverses réponses. Un exemple classique est : • une page d'erreurs si la demande n'a pu être traitée correctement • une page de confirmation sinon e. La méthode execute rend au contrôleur C un résultat de type chaîne de caractères appelée clé de navigation. [actions.Action1].execute peut produire deux clés de navigation "page1" et "page2". La méthode [actions.Action1].execute va également mettre à jour le modèle M [2c] que va exploiter la page JSP envoyée en réponse. Ce modèle peut comporter des éléments de : • la classe [actions.Action1] instanciée • la session de l'utilisateur 11 12 6 MVC de Struts 2 : fonctionnement Exemple simple 3. Réponse Le HelloWorld… le contrôleur C demande à la page JSP correspondant à la clé de navigation de s'afficher [3]. C'est la vue, le V de MVC. La page JSP utilise un modèle M pour initialiser les parties dynamiques de la réponse qu'elle doit envoyer au client. 13 14 7 Struts 2 : clés de navigation Struts 2 : clés de navigation Définies dans struts.xml Utilisées dans l’Action : <struts> public class Action1 extends ActionSupport{ <package name="default" namespace="/" extends="struts-default"> private String param1="valeur1"; <default-action-ref name="index" /> private String param2="valeur2"; <action name="index"> <result type="redirectAction"> @Override <param name="actionName">Action1</param> <param name="namespace">/actions</param> public String execute(){ </result> </action> int i=(int)(Math.random()*2); // choix aléatoire entre deux vues </package> if(i==0){ <package name="actions" namespace="/actions" extends="struts-default"> return "page1"; <action name="Action1" class="actions.Action1"> }else{ <result name="page1">/vues/Page1.jsp</result> return "page2"; <result name="page2">/vues/Page2.jsp</result> } </action> } </package> // getters et setters </struts> ... 15 } 16 8 Struts 2 : clés de navigation Struts 2 : clés de navigation Utilisées dans l’Action : Valeurs prédéfinies : La définition d’une Action héritant de ActionSupport offre des constantes prédéfinies de clés de navigation public class Action1 extends ActionSupport{ private String param1="valeur1"; private String param2="valeur2"; @Override public String execute(){ Constante Valeur int i=(int)(Math.random()*2); // choix aléatoire entre deux vues SUCCESS "success" if(i==0){ ERROR "error" INPUT "input" LOGIN "login" return "page1"; }else{ return "page2"; } Plus internationalisation (getText…) } // getters et setters ... } 17 18 9 Exemple simple 2 Exemple simple : struts.xml <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <constant name="struts.enable.DynamicMethodInvocation" value="false" /> <constant name="struts.devMode" value="false" /> <package name="exemple.actions" namespace="/" extends="struts-default"> <!-- Action de l'action de réference --> <default-action-ref name="saisir_Personne"/> <action name="saisir_Personne"> <result>/jsp/saisir_Personne.jsp</result> </action> … 19 20 10 Exemple simple : struts.xml Exemple simple : PersonneAction.java <action name="enregistrer_Personne" class="exemple.actions.PersonneAction" method="enregistrer"> <result name="success" >/jsp/enregistrer_Personne.jsp</result> <result name="input">/jsp/saisir_Personne.jsp</result> </action> <action name="lister_Personne" class="exemple.actions.PersonneAction" method="lister"> <result name="success">/jsp/lister_Personne.jsp</result> </action> <action name="supprimer_Personne" class="exemple.actions.PersonneAction" method="supprimer"> <result name="success">/jsp/lister_Personne.jsp</result> </action> Bean Personne + Action : package exemple.actions; public class PersonneAction extends ActionSupport { private int identifiant; private String pseudo; private String mail; private String codePostal; private java.util.Date dateInscription; private static ArrayList<Personne> listPersonnes = new ArrayList<Personne>( ); // getters et setters </package> </struts> 21 22 11 Balises d’appels Exemple simple : PersonneAction.java public String enregistrer() { if(this.pseudo.equals("")) { addFieldError("pseudo", "le pseudo ne doit pas être vide"); return INPUT; } Personne pers = new Personne (); pers.setIdentifiant(identifiant); pers.setPseudo(pseudo); pers.setMail(mail); pers.setCodePostal(codePostal); pers.setDateInscription(dateInscription); listPersonnes.add(pers); return SUCCESS; } public String lister(){ return SUCCESS; } public String supprimer(){ listPersonnes.removeAll(getListPersonnes()); return SUCCESS; } } 23 Appels depuis une JSP : balises Struts <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title><s:text name="formulaire.titre1"/></title> </head> <body> <h1><s:text name="formulaire.titre2"/></h1> <s:form action="DoSomething"> <s:submit key="formulaire.execute"/> <s:submit key="formulaire.action1" method="action1"/> <s:submit key="formulaire.action2" action="DoSomethingElse" method="action2"/> </s:form> <s:url id="url" action="DoSomething" method="action3"/> <s:a href="%{url}"><s:text name="formulaire.action3"/></s:a> </body> 24 </html> 12 Autre méthode Autre méthode Pour l’accès aux données d’un formulaire, création d’une classe Data avec UNIQUEMENT les données Puis de la classe de Action : public class Form2 extends ActionSupport implements ModelDriven { public class Data { // constructeur sans paramètre // constructeur sans paramètre public Data() { public Form2() { } } // champs du formulaire // modèle de l'action private String textfield = "texte"; public Object getModel() { return new Data(); private String password = "secret"; } private String textarea = "ligne1\nligne2\n"; } private String select1 = "zéro"; private String[] select1Values = new String[]{"zéro", "un", "deux"}; … // valeurs sélectionnées dans champ select3 public String getSelect3SelectedValues() { return getValue(select3); } … // getters et setters 25 26 13 Autre méthode Gestion des sessions public class Confirmer extends ActionSupport implements SessionAware{ // modèle private String nom; // session private Map<String, Object> session; Dans la JSP : <s:form name="formulaire"> <s:textfield name="textfield" key="Form.textfield" /> <s:password name="password" key="Form.password"/> // getters et setters … @Override public void setSession(Map<String, Object> session) { this.session=session; } <s:textarea name="textarea" key="Form.textarea" cols="40" rows="5"/> <s:select name="select1" list="select1Values" size="1" key="Form.select1" headerValue="<--select 1 --> <s:select name="select2" size="3" list="select2Values" key="Form.select2"/> <s:select name="select3" size="3" list="select3Values" key="Form.select3" multiple="true"/> <s:radio name="radio" list="radioValues" key="Form.radio"/> @Override public String execute(){ // on met un attribut « nom » dans la session session.put("nom",nom); // navigation return SUCCESS; } <s:checkbox name="checkbox" key="Form.checkbox"/> <s:checkboxlist name="checkboxlist" list="checkboxlistValues“ <s:submit key="Form.submitText" name="submitText"/> </s:form> } 27 28 14 Intercepteurs Intercepteurs par défaut Avant l’appel à la méthode execute, traverse les intercepteurs 29 <interceptor-stack name="defaultStack"> <interceptor-ref name="exception"/> <interceptor-ref name="alias"/> <interceptor-ref name="servletConfig"/> <interceptor-ref name="i18n"/> <interceptor-ref name="prepare"/> <interceptor-ref name="chain"/> <interceptor-ref name="debugging"/> <interceptor-ref name="scopedModelDriven"/> <interceptor-ref name="modelDriven"/> <interceptor-ref name="fileUpload"/> <interceptor-ref name="checkbox"/> <interceptor-ref name="multiselect"/> <interceptor-ref name="staticParams"/> <interceptor-ref name="actionMappingParams"/> <interceptor-ref name="params"> <param name="excludeParams">dojo\..*,^struts\..*</param> </interceptor-ref> <interceptor-ref name="conversionError"/> <interceptor-ref name="validation"> <param name="excludeMethods">input,back,cancel,browse</param> </interceptor-ref> <interceptor-ref name="workflow"> 30 15 Intercepteurs utilisation Intercepteurs exemple Utilisés pour la conversion de type et la validation de paramètres Intercepteur Validation : pas appelé si méthode input, back, cancel ou browse 31 Déclaration Integer dans Modèle - formulaire <action name="FormInt" class="example.FormInt"> <result name="input">/example/FormInt.jsp</result> <result name="cancel“ type="redirect">/example/Accueil.jsp</result> <result name="success"> /example/OKFormInt.jsp</result> </action> 32 16 Intercepteurs exemple Intercepteurs exemple Déclaration int dans Modele - formulaire Déclaration formulaire public class FormInt extends ActionSupport implements ModelDriven, SessionAware { // constructeur sans paramètre public FormInt() { } // modèle de l'action public Object getModel() { if (session.get("model") == null) { session.put("model", new FormIntModel()); … // validation @Override public void validate() { // saisie int6 valide ? if (getFieldErrors().get("int6") == null) { int int6 = Integer.parseInt(((FormIntModel) getModel()).getInt6()); if (int6 < 2 || int6 > 20) { addFieldError("int6", getText("int6.error")); } } 33 <body background="<s:url value="/ressources/standard.jpg"/>"> <h2><s:text name="FormInt.message"/></h2> <s:form name="formulaire" action="FormInt"> <s:textfield name="int1" key="int1.prompt"/> <s:textfield name="int2" key="int2.prompt"/> <s:textfield name="int3" key="int3.prompt"/> <s:textfield name="int4" key="int4.prompt"/> <s:textfield name="int5" key="int5.prompt"/> <s:textfield name="int6" key="int6.prompt"/> <s:submit key="Form.submitText" method="execute"/> </s:form> <br/> <s:url id="url" action="FormInt" method="cancel"/> <s:a href="%{url}"><s:text name="Form.cancelText"/></s:a> <br/> <s:url id="url" action="FormInt" method="clearModel"/> <s:a href="%{url}"><s:text name="Form.clearModel"/></s:a> </body> 34 17 Intercepteurs exemple Intercepteurs exemple FormInt-validation.xml : chaîne FormInt-validation.xml : Integer <validators> <validators> <field name="int1" > <field-validator type="requiredstring" short-circuit="true"> <message key="int1.error"/> </field-validator> <field-validator type="regex" short-circuit="true"> <param name="expression">^\d{2}$</param> <param name="trim">true</param> <message key="int1.error"/> </field-validator> </field> <field name="int5" > <field-validator type="required" short-circuit="true"> <message key="int5.error"/> </field-validator> <field-validator type="conversion" short-circuit="true"> <message key="int2.error"/> </field-validator> <field-validator type="int" short-circuit="true"> <param name="min">1</param> <param name="max">10</param> <message key="int5.error"/> </field-validator> </field> </validators> <field name="int2" > ... </field> ... </validators> 35 36 18 Struts 1 vs Struts 2 Struts 1 vs Struts 2 Comparaison en 10 points : Action classes Struts 1 impose aux Actions d’hériter d’une classe abstraite. Struts 2 Action peuvent implémenter l’interface Action, et/ou d’autres interfaces. Struts 2 fournit une classe de base ActionSupport d’implémentation. Sinon, utilisation d’objet POJO. – Action classes – Threading Model – Servlet Dependency – Testability – Harvesting Input – Expression Language – Binding values into views – Type Conversion – Validation – Control Of Action Execution 37 38 19 Struts 1 vs Struts 2 Threading Model Struts 1 Actions are singletons and must be threadsafe since there will only be one instance of a class to handle all requests for that Action. The singleton strategy places restrictions on what can be done with Struts 1 Actions and requires extra care to develop. Action resources must be thread-safe or synchronized. Struts 2 Action objects are instantiated for each request, so there are no thread-safety issues. (In practice, servlet containers generate many throwaway objects per request, and one more object does not impose a performance penalty or impact garbage collection.) 39 Struts 1 vs Struts 2 Servlet Dependency Struts 1 Actions have dependencies on the servlet API since the HttpServletRequest and HttpServletResponse is passed to the execute method when an Action is invoked. Struts 2 Actions are not coupled to a container. Most often the servlet contexts are represented as simple Maps, allowing Actions to be tested in isolation. Struts 2 Actions can still access the original request and response, if required. However, other architectural elements reduce or eliminate the need to access the HttpServetRequest or HttpServletResponse directly. 40 20 Struts 1 vs Struts 2 Struts 1 vs Struts 2 Testability A major hurdle to testing Struts 1 Actions is that the execute method exposes the Servlet API. A thirdparty extension, Struts TestCase, offers a set of mock object for Struts 1. Struts 2 Actions can be tested by instantiating the Action, setting properties, and invoking methods. Dependency Injection support also makes testing simpler. . 41 Harvesting Input Struts 1 uses an ActionForm object to capture input. Like Actions, all ActionForms must extend a base class. Since other JavaBeans cannot be used as ActionForms, developers often create redundant classes to capture input. DynaBeans can used as an alternative to creating conventional ActionForm classes, but, here too, developers may be redescribing existing JavaBeans. Struts 2 uses Action properties as input properties, eliminating the need for a second input object. Input properties may be rich object types which may have their own properties. The Action properties can be accessed from the web page via the taglibs. Struts422 also supports the ActionForm pattern, as well as 21 Struts 1 vs Struts 2 Struts 1 vs Struts 2 Expression Language Struts 1 integrates with JSTL, so it uses the JSTL EL. The EL has basic object graph traversal, but relatively weak collection and indexed property support. Struts 2 can use JSTL, but the framework also supports a more powerful and flexible expression language called "Object Graph Notation Language" (OGNL). 43 Binding values into views Struts 1 uses the standard JSP mechanism for binding objects into the page context for access. Struts 2 uses a "ValueStack" technology so that the taglibs can access values without coupling your view to the object type it is rendering. The ValueStack strategy allows reuse of views across a range of types which may have the same property name but different property types. 44 22 Struts 1 vs Struts 2 Struts 1 vs Struts 2 Type Conversion Struts 1 ActionForm properties are usually all Strings. Struts 1 uses Commons-Beanutils for type conversion. Converters are per-class, and not configurable per instance. Struts 2 uses OGNL for type conversion. The framework includes converters for basic and common object types and primitives. 45 Validation Struts 1 supports manual validation via a validate method on the ActionForm, or through an extension to the Commons Validator. Classes can have different validation contexts for the same class, but cannot chain to validations on sub-objects. Struts 2 supports manual validation via the validate method and the XWork Validation framework. The Xwork Validation Framework supports chaining validation into sub-properties using the validations defined for the properties class type and the validation context. 46 23 Struts 1 vs Struts 2 Control Of Action Execution Struts 1 supports separate Request Processors (lifecycles) for each module, but all the Actions in the module must share the same lifecycle. Struts 2 supports creating different lifecycles on a per Action basis via Interceptor Stacks. Custom stacks can be created and used with different Actions, as needed. 47 24
Documents pareils
Fiche Cours PDF - Ociensa Technologies
- Les différences de Struts 2 par rapport à Struts 1
Plus en détailTD n 3 - struts 2 1 Struts 2 Travail demandé
4. Ajouter un validator pour votre formulaire (méthode validate dans votre action) pour que le nom et prénom soient obligatoires et que le mot de passe fasse plus de 8 caractères. 5. Utiliser les f...
Plus en détail