La presentazione è in caricamento. Aspetta per favore

La presentazione è in caricamento. Aspetta per favore

Facelets case study: Ricettario Docente: Gabriele Lombardi

Presentazioni simili


Presentazione sul tema: "Facelets case study: Ricettario Docente: Gabriele Lombardi"— Transcript della presentazione:

1 Facelets case study: Ricettario Docente: Gabriele Lombardi ilgabbio@yahoo.it

2 Sommario SLIDECONTENUTO Scopo Descrizione dello scopo del mini-progetto. Modello dei dati Un domain-model mappato con JPA. Interfaccia web Componenti facelet e utilizzo di primefaces. Business layer Funzionalità ed esposizione con WS. Architettura Come utilizzare JEE per questo progetto.

3 Scopo Realizzare una piccola applicazione web che: –permetta di creare/editare/eliminare/cercare delle ricette di cucina memorizzate in un database; –sia realizzata secondo il modello three-tier; –abbia uninterfaccia web MVC modulare; –offra le proprie funzionalità anche via web-service. Strumenti utilizzati (in GlassFish): –JPA per la persistenza; –EJB per il business-tier; –Facelet con componenti custom per lapp web; –JAX-WS per i web-services;

4 Pagina JSF con sintassi Facelet Controller di componente Componente composita Facelet Controller di pagina JSF Architettura EJB con logica di business Endpoint JAX-WS JavaDB ORM con JPA Ricetta TipoPiatto Ingrediente Modello dei dati come JavaBeans Data tier Business tier Controller di pagina JSF Persistence provider Injection Pagina JSF con sintassi Facelet Injection Espressioni EL Componente composita Facelet Controller di componente Espressioni EL Presentation tier EJB con logica di business

5 Modello dei dati Utilizziamo dei «normali» JavaBeans; mappiamo la struttura dati sul DB con JPA; mappiamo la struttura dati sullXML con JAX-B. @MappedSuperclass public class DomainObject implements Serializable { @Id @GeneratedValue private Long id; … } @Entity @XmlAccessorType(XmlAccessType.FIELD) public class Recipe extends DomainObject { @Column(nullable = false, length = 64) @XmlAttribute(required = true) private String name; @Lob @Column(nullable = false) private String description; @Enumerated private PlateType plateType; @OneToMany(cascade = CascadeType.ALL) @XmlElementWrapper(name = "ingredients") @XmlElement(name = "ingredient") private List ingredients; … } @Entity public class Ingredient extends DomainObject{ @Column(nullable = false, length = 64) private String name; @Lob private String comment; @Column(nullable = false, length = 16) private String quantity; … }

6 Modello dei dati Configurazione di JPA in persistence.xml Configurazione del DataSource JNDI: –in GlassFish (o con file apposito di configurazione). org.eclipse.persistence.jpa.PersistenceProvider jdbc/Ricettario com/gab/tests/j2ee/ricettario/core/entities/queries.xml Connection pool Risorsa JNDI

7 Business layer Definire le query in un file XML: –in persistence.xml abbiamo detto: – …/queries.xml com.gab.tests.j2ee.ricettario.core.entities SELECT r FROM Recipe r SELECT r FROM Recipe r WHERE lower(r.name) LIKE lower(:namePart) SELECT r FROM Recipe r, IN(r.ingredients) i WHERE lower(i.name) LIKE lower(:namePart) Tutte le ricette Ricette con like sul nome (parametro) Ricette con like sul nome dellingrediente

8 Business layer Implementazione di un EJB: –Stateless ogni richiesta è indipendente dalle altre: –è il tipo di EJB di sessione (con risultato) più efficiente, uno può essere condiviso tra svariati client in thread concorrenti. –annotato con JAX-WS per offrirsi come WebService; –con iniezione per laccesso alla persistenza; –i metodi sono automaticamente transazionali (JTA). @Local public interface RecipesBean { public Recipe save(Recipe recipe); public List getAll(); public List getNameLike(String namePart); public List getIngredientNameLike(String namePart); public void delete(Recipe recipe); } @Stateless @WebService public class RecipesBeanImpl implements RecipesBean { @PersistenceContext(unitName = "RicettarioCorePU") private EntityManager em; @Override public Recipe save(Recipe recipe) {…} @Override @WebResult(name = "recipe") public List getAll() {…} @Override public void delete(@WebParam(name = "recipe") Recipe recipe) {…} @Override public List getNameLike(String namePart) {…} @Override public List getIngredientNameLike(String namePart) { return em.createNamedQuery("Recipe.getIngredientLike", Recipe.class).setParameter("namePart", "%" + namePart.trim() + "%").getResultList(); }

9 Interfaccia Web: la componente Ha un controller proprio: –ne implementa le operazioni e ne mantiene lo stato. Ha una view propria: –definita con sintassi Facelet usando il namespace cc. @FacesComponent("recipeEditor") public class RecipeEditor extends UIPanel implements NamingContainer { private Recipe recipe; public Recipe getRecipe() { if (recipe == null) { recipe = (Recipe)getValueExpression("value").getValue(FacesContext.getCurrentInstance().getELContext()); } return recipe; } @Override public String getFamily() { return UINamingContainer.COMPONENT_FAMILY; } … // Operazioni implementate qui } <cc:attribute name="value" required="true" type="com.gab.tests.j2ee.ricettario.core.entities.Recipe"/> … <p:commandButton icon="ui-icon-closethick" title="Elimina immediate="true" process="@this" update="@form" onclick="if (!confirm('Sicuro?')) { return false; }" action="#{cc.removeIngredient(ingredient)}"/>

10 Interfaccia Web: Il controller di pagina La pagina: –è una facelet «normale» che utilizza la componente; –il controller da accesso allo strato di business. © 2013 - ECOLE @ManagedBean(name = "recipes") @ViewScoped public class RecipesController implements Serializable { // Iniezione dellEJB con lo strato di business. @EJB private RecipesBean rb; // Attributi ed operazioni qui che usano lEJB. }

11 Interfaccia Web


Scaricare ppt "Facelets case study: Ricettario Docente: Gabriele Lombardi"

Presentazioni simili


Annunci Google