Struts 2 : esempio di CRUD utilizzando Convention Plugin e Tiles 2
Questo è un semplice esempio di una applicazione web che gestisce tutte le operazione base sui dati, ovvero quello che in genere viene chiamato CRUD (Create, Read, Update, Delete).
Viene visualizzato un elenco di libri, con la possibilità di inserirne di nuovi o di modificare o eliminare quelli esistenti:
La struttura della applicazione web
Innanzi tutto la semplice struttura di questa applicazione. E’ composta da due namespace e dalle relative action:
- Namespace “/” con le action:
- index
- biblioteca
- Namespace “biblioteca/” con le action:
- nuovo
- salva
- modifica
Tanto per intenderci questi sono i relativi url (dando per scontato che la base dell’applicazione sia http://localhost:8080/crud:
- http://localhost:8080/crud/index
- http://localhost:8080/crud/biblioteca
- http://localhost:8080/crud/biblioteca/nuovo
- http://localhost:8080/crud/biblioteca/salva
- http://localhost:8080/crud/biblioteca/modifica
La definizione delle action
All’interno del file struts.xml ho definito solo l’action /index del namespace “/” impostandolo come action di default. In più, visto che uso Tiles2 per la gestione del layout, c’è anche la definizione del result-type relativo:
<struts> <constant name="struts.devMode" value="true" /> <constant name="struts.action.extension" value=","/> <package name="default" extends="struts-default"> <result-types> <result-type name="tiles" class="org.apache.struts2.views.tiles.TilesResult" /> </result-types> </package> <package name="root" namespace="/" extends="default"> <default-action-ref name="index" /> <action name="index"> <result type="tiles" name="success">siteLayout</result> </action> </package> </struts>
Ricapitolando le action sono:
- /biblioteca
- /biblioteca/nuovo
- /biblioteca/salva
- /biblioteca/modifica
L’action “/biblioteca” viene definita in questo modo nella classe Libri:
@ParentPackage("default") @Namespace("/") @Results({ @Result(name = "vai-alla-biblioteca", location = "biblioteca", type="tiles"), }) @Action(value = "/biblioteca") public class Libri extends ActionSupport implements ServletRequestAware { [...] private List<Libro> lista; public String execute() { // Leggo in qualche modo la lista dei libri [...] return "vai-alla-biblioteca"; } public List<Libro> getLista() { return lista; } public void setLista(List<Libro> lista) { this.lista = lista; } }
Definita in questo modo questa action:
- Eredita le definizione del package default (@ParentPackage(“default”))
- Appartiene al namespace “/” (@Namespace(“/”))
- Definisce un result di tipo tiles (@Result(name = “vai-alla-biblioteca”, location = “biblioteca”, type=”tiles”))
La classe LibroCrud definisce le altre action:
@ParentPackage("default") @Namespace("biblioteca") @Results({ @Result(name = "libro", type="tiles", location = "libro"), @Result(name = "biblioteca", type="redirect", location = "/biblioteca"), }) public class LibroCrud extends ActionSupport implements ServletRequestAware { [...] @Action(value = "/nuovo") public String nuovo() { return "libro"; } @Action(value = "/salva") public String salva() { //Qui c'è la logica di salvataggio di un libro [...] return "biblioteca"; } @Action(value = "/elimina") public String elimina() { [...] //Qui c'è la logica di eliminazione di un libro [...] return "biblioteca"; } @Action(value = "/modifica") public String modifica() { [...] //Qui c'è la logica di modifica di un libro [...] return "libro"; } [...] }
Definita in questo modo questa action:
- Eredita le definizione del package default (@ParentPackage(“default”))
- Appartiene al namespace “/biblioteca” (@Namespace(“biblioteca”))
- Definisce i results di tipo tiles
@Result(name = “libro”, type=”tiles”, location = “libro”),@Result(name = “biblioteca”, type=”redirect”, location = “/biblioteca”)
La configurazione di Tiles
Utilizzo solo 3 tiles:
- siteLayout: la mia homepage -> homepage.jsp
- biblioteca: la pagina con l’elenco dei libri -> biblioteca.jsp
- libro: la pagina di inserimento/modifica di un libro -> libro.jsp
<tiles-definitions> <!-- Layout principale --> <definition name="siteLayout" template="/WEB-INF/pages/template/siteLayout.jsp"> <put-attribute name="title" value="Crea, leggi, modifica e cancella!" /> <put-attribute name="header" value="/WEB-INF/pages/header.jsp" /> <put-attribute name="body" value="/WEB-INF/pages/homepage.jsp" /> <put-attribute name="footer" value="/WEB-INF/pages/footer.jsp" /> </definition> <!-- Definizione della pagina "biblioteca" --> <definition name="biblioteca" extends="siteLayout"> <put-attribute name="title" value="La mia Biblioteca" /> <put-attribute name="body" value="/WEB-INF/pages/biblioteca/biblioteca.jsp" /> </definition> <!-- Definizione della pagina "libro" --> <definition name="libro" extends="siteLayout"> <put-attribute name="title" value="Libro" /> <put-attribute name="body" value="/WEB-INF/pages/biblioteca/libro.jsp" /> </definition> </tiles-definitions>
Le pagine jsp
In queso piccolo esempio sono solo due:
biblioteca.jsp
Definita in questo modo:
<table border="2" cellpadding=10> <thead> <tr> <th></th> <th>id</th> <th>Titolo</th> <th>Autore</th> <th>Creato il</th> <th>Modificato il</th> </tr> </thead> <tbody> <s:iterator value="lista"> <tr> <td> <s:url action="modifica" var="urlModifica" namespace="biblioteca" > <s:param name="id"><s:property value="id"/></s:param> </s:url> (<a href="<s:property value="#urlModifica" />" >Modifica</a>) <s:url action="elimina" var="urlElimina" namespace="biblioteca" > <s:param name="id"><s:property value="id"/></s:param> </s:url> (<a href="<s:property value="#urlElimina" />" >Elimina</a>) </td> <td><s:property value="id"/></td> <td><s:property value="titolo"/></td> <td><s:property value="autore"/></td> <td><s:property value="created"/></td> <td><s:property value="updated"/></td> </tr> </s:iterator> </tbody> </table>
e libro.jsp
Il cui codice è:
<s:url namespace="/" action="biblioteca" var="biblioteca" /> <p><a href="<s:property value="#biblioteca" />"> Torna alla Biblioteca</a></p> <s:form action="salva" namespace="biblioteca"> <s:textfield name="id" label="Id"></s:textfield> <s:textfield name="titolo" label="Titolo"></s:textfield> <s:textfield name="autore" label="Autore"></s:textfield> <s:submit value="Salva"></s:submit> </s:form>
Tutto quà. Se volete vederlo in azione scaricate il progetto.
Scarica il progetto di esempio
Commenti recenti