Java lezione 18

25
Architettura Model1 :

Transcript of Java lezione 18

Page 1: Java lezione 18

Architettura Model1 :

Page 2: Java lezione 18

Model 2 (MVC):

La richiesta del client viene sempre acquisita da una servlet che poi smista il flusso verso l’opportuna pagina JSP.

La servlet quindi funge da processore di interfaccia con l’utente e gestisce operazioni come l’autenticazione, il logging.

Page 3: Java lezione 18

Modello MVC:

Il controller servlet incoraggia una maggiore estendibilità e riuso delle classi. Infatti nel modello MVC si ha una netta separazione tra la business-logic, la presentazione e la gestione delle richieste.

Il modello MVC può sembrare complesso, ma in realtà semplifica le applicazioni, soprattutto per ciò che riguarda il loro mantenimento e la loro estendibilità.

Model

Si tratta di normali classi Java o Bean che sono in contatto diretto con una base di dati. Nei casi delle applicazioni più complesse si avranno degli EJB.

View

Si tratta di pagine HTML, di JSP.

Control

Si tratta di una servlet con i compiti di unico punto d’ingresso dell’applicazione e di supervisor.

Page 4: Java lezione 18

Redirect e Forward

Il controller ha il compito, come detto, di smistare il flusso dell’applicazione a diversi viewer (JSP). Esistono due modalità per effettuare questo:

response.sendRedirect(response.encodeRedirectURL(redirectStr));in tal caso si ha una richiesta completamente nuova verso la

pagina didestinazione e lo stato attuale memorizzato in request viene

perso.Spesso tuttavia è necessario conservare il contenuto di request, considerando soprattutto che nel caso del controller il request contiene i parametri inviati dall’utente:

RequestDispatcher dispatcher =req.getRequestDispatcher( redirectStr );

dispatcher.forward( req, resp );

Page 5: Java lezione 18

Connection Pooling

Una delle operazioni più dispendiose di un’applicazione è l’apertura della connesione con il database, soprattutto se si apre una connessione per eseguire solo poche query. E’ quindi preferibile aprire un certo numero di connessioni all’avvio dell’applicazione e porle in un ‘pool’ in modo che possano essere utilizzate all’occorrenza.

In pratica la il pool di connessioni contiene un Vector di Connection da cui posso recuperarne una in caso di necessità, segnandola come occupata, e restituendola al pool quando non serve più.

Questo può essere fatto in modo manuale crendo delle classi opportune, oppure è possibile utilizzare il package javax.sql.

Page 6: Java lezione 18

PooledConnection

import java.sql.*;public class PooledConnection {

private Connection connection = null;private boolean inuse =false;

// Costruttore che memorizza la connessione JDBCpublic PooledConnection(Connection value){ if(value != null){connection = value;} }

// Restituisce un riferimento alla connessione JDBCpublic Connection getConnection() {return connection;}

// Imposta lo stato di PooledConnection.public void setInUse(boolean value) {inuse = value;}

// Restituisce lo stato corrente di PooledConnection.public boolean inUse() {return inuse;}

// Chiude la connessione JDBCrealepublic void close ()

{ try { connection.close(); } catch(SQLException sqle){System.err.println(sqle.getMessage()) ; }}

}

Page 7: Java lezione 18

Connection Pool – prima parteimport java.sql.*;import java.util.*;import java.io.Serializable;public class ConnectionPool implements Serializable{

private String driver = null;private String url = null;private int size = 0; // Numero iniziale di connessioni.private String username = new String("");private String password = new String("");private Vector pool = null; // Vettore di connessioni JDBCpublic ConnectionPool(){}public void setDriver(String value){if(value != null){driver = value;}}public String getDriver(){return driver; }public void setURL(String value){if(value != null){url = value;}}public String getURL(){return url;}public void setSize(int value){if(value > 1){size = value;}}public int getSize(){return size;}public void setUsername(String value){if(value != null){username=

value;}}public String getUserName(){return username;}public void setPassword(String value){if(value != null){password = value;}}public String getpassword(){return password;}

Page 8: Java lezione 18

Connection Pool – seconda parte

// Crea e restituisce una connessioneprivate Connection createConnection() throws Exception{

Connection con = null;con = DriverManager.getConnection(url,username,password);return con;

}// Aggiunge PooledConnectional pool

private void addConnection(PooledConnection value){// Se il pool è null, crea un nuovo vettore// con la dimensione iniziale "size"if(pool == null){pool = new Vector(size);}// Aggiunge l'oggetto PooledConnection al vettorepool.addElement(value) ;

}

Page 9: Java lezione 18

Connection Pool – terza parte

// Inizializza il poolpublic synchronized void initializePool() throws Exception{ if(driver == null) throw new Exception("No Driver Name Specified!");

if(url == null) throw new Exception("No URL Specified!");if(size < 1) throw new Exception("Pool size is less than 1!");

// Crea le connessionitry{ Class.forName(driver); for(int x = 0; x < size; x++){ Connection con = createConnection(); if(con != null) { PooledConnection pcon = new PooledConnection(con);

addConnection(pcon) ; } }}catch(Exception e){

System.err.println(e.getMessage());throw new Exception(e.getMessage());}

}

Page 10: Java lezione 18

Connection Pool – quarta parte

public synchronized void releaseConnection(Connection con){// trova l'oggetto PooledConnectionfor(int x = 0; x < pool.size(); x++){

PooledConnection pcon = (PooledConnection)pool.elementAt(x);

// Verifica se la connessione è correttaif(pcon.getConnection() == con){

System.err.println("Releasing Connection " + x);// Imposta l'attributo inuse a false, che// rilascia per l'usopcon.setInUse(false);break;

}}

}

Page 11: Java lezione 18

Connection Pool – quinta parte

// Trova una connessione disponibilepublic synchronized Connection getConnection() throws Exception{

PooledConnection pcon = null;for(int x = 0; x < pool.size(); x++){

pcon = (PooledConnection)pool.elementAt(x);if(pcon.inUse() == false){pcon.setInUse(true); return pcon.getConnection();}

}// Non è riuscito a trovare una connessione libera, ne crea e aggiunge

unatry{ Connection con = createConnection();

pcon = new PooledConnection(con);pcon.setInUse(true);pool.addElement(pcon);

}catch (Exception e){ System.err.println(e.getMessage());throw new Exception(e.getMessage());}

return pcon.getConnection();}

Page 12: Java lezione 18

Connection Pool – sesta parte

// Quando si chiude il pool, occorre prima svuotarlo.public synchronized void emptyPool(){

for(int x = 0; x < pool.size(); x++){System.err.println("Chiusura connessione JDBC" + x);PooledConnection pcon

=(PooledConnection)pool.elementAt(x);if(pcon.inUse() == false) pcon.close();else{ // Se è in uso, attende 30 secondi e forza la chiusura.

try{ java.lang.Thread.sleep(30000);pcon.close();

}catch(InterruptedException ie){System.err.println(ie.getMessage());

}}

}}

}

Page 13: Java lezione 18

Un sito di e-commerce

Un utente deve poter effettuare le seguenti operazioni:

•Ricerca di un prodotto per nome o descrizione•Scorrere la lista dei prodotti scelta la categoria•Vedere i dettagli dei prodotti•Porre un prodotto in un carrello della spesa•Vedere e modificare il contenuto del carrello•Eseguire un ordine

Page 14: Java lezione 18

Struttura del database

CategorieCatIDDescrizione

ProdottiProdIdCatIdNomeDescrizionePrezzo

OrdiniOrdIdClienteIndirizzoData

DettOrdiniIdOrdIdProdIdQuantitàPrezzo

Page 15: Java lezione 18

Struttura delle pagine

<HTML> <BODY>

<TABLE> <TR>

<!–– header ––> </TR> <TR>

<TD VALIGN="TOP"> <!–– menu ––> </TD> <TD VALIGN="TOP"> <!–– page content––> </TD>

</TR> </TABLE>

</BODY> </HTML>

Page 16: Java lezione 18

Configurazioni

server.xml:<Context path="/burnaby" docBase="burnaby" debug="0" reloadable="true"> </Context>

Page 17: Java lezione 18

Architettura e aspetto

Page 18: Java lezione 18

Carrello e Ordini

Page 19: Java lezione 18

Il file web.xml<servlet> <servlet-name>ControllerServlet</servlet-name> <servlet-class>ControllerServlet</servlet-class> <init-param>

<param-name>base</param-name> <param-value>http://localhost:8080/burnaby/servlet/ControllerServlet</

param-value> </init-param> <init-param> <param-name>jdbcDriver</param-name> <param-value>sun.jdbc.odbc.JdbcOdbcDriver</param-value> </init-param> <init-param> <param-name>imageUrl</param-name> <param-value>http://localhost:8080/burnaby/images/</param-value> </init-param> <init-param> <param-name>dbUrl</param-name> <param-value>jdbc:odbc:Burnaby</param-value> </init-param> <init-param> <param-name>dbUserName</param-name>

<param-value></param-value> </init-param> <init-param> <param-name>dbPassword</param-name> <param-value></param-value> </init-param>

</servlet>

Page 20: Java lezione 18

Il controller (inizializzazione)import java.sql.*; import javax.servlet.*; import javax.servlet.http.*; import java.io.*; import java.util.*; import com.brainysoftware.burnaby.DbBean; public class ControllerServlet extends HttpServlet { /**Initialize global variables*/ public void init(ServletConfig config) throws ServletException {

ServletContext context = config.getServletContext(); context.setAttribute("base", config.getInitParameter("base")); context.setAttribute("imageUrl", config.getInitParameter("imageUrl")); DbBean dbBean = new DbBean(); dbBean.setDbUrl(config.getInitParameter("dbUrl"));

dbBean.setDbUserName(config.getInitParameter("dbUserName")); dbBean.setDbPassword(config.getInitParameter("dbPassword")); context.setAttribute("dbBean", dbBean);

try { // loading the database JDBC driver Class.forName(config.getInitParameter("jdbcDriver"));

} catch (ClassNotFoundException e) { System.out.println(e.toString()); } super.init(config);

} Si noti l’utilizzo so ServletContext per rendere disponibili le variabili per tutta l’applicazione

Page 21: Java lezione 18

Il controller doGet doPost/**Process the HTTP Get request*/ public void doGet(HttpServletRequest request, HttpServletResponse response) throws  ServletException, IOException { doPost(request, response); } /**Process the HTTP Post request*/ public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String base = "/jsp/"; String url = base + "Default.jsp"; String action = request.getParameter("action"); if (action!=null) { if (action.equals("search")) url = base + "SearchResults.jsp"; else if (action.equals("browseCatalog")) url = base + "BrowseCatalog.jsp"; else if (action.equals("productDetails")) url = base + "ProductDetails.jsp"; else if (action.equals("addShoppingItem") || action.equals("updateShoppingItem") || action.equals("deleteShoppingItem") || action.equals("displayShoppingCart")) url = base + "ShoppingCart.jsp"; else if (action.equals("checkOut")) url = base + "CheckOut.jsp"; else if (action.equals("order")) url = base + "Order.jsp"; } RequestDispatcher requestDispatcher = getServletContext().getRequestDispatcher(url); requestDispatcher.forward(request, response); } }

Page 22: Java lezione 18

Classi di supportoProduct.javapackage com.brainysoftware.burnaby; public class Product {

public int id; public String name; public String description; public double price;

}

ShoppingItem.javapackage com.brainysoftware.burnaby; public class ShoppingItem {

public int productId; public String name; public String description; public double price; public int quantity;

}

Page 23: Java lezione 18

File Inclusi: header.jspSi recuperano dal ServerContext i valor base e imageUrl:

<% String base = (String) application.getAttribute("base"); String imageUrl = (String) application.getAttribute("imageUrl"); %>

<TABLE WIDTH="740" CELLPADDING="0" HEIGHT="75" CELLSPACING="0" BORDER="0"> <TR>

<TD ALIGN="left" BGCOLOR="F6F6F6"> <FONT FACE="Verdana" SIZE="4">Burnaby e-Mall</FONT>

</TD> <TD ALIGN="RIGHT" BGCOLOR="F6F6F6"> <A HREF="<%=base%>?action=displayShoppingCart"> <IMG BORDER="0" SRC="<%=(imageUrl + "cart.gif")%>">

</A> &nbsp;&nbsp;&nbsp; </TD>

</TR> </TABLE>

Page 24: Java lezione 18

File Incluse: menu.jsp<%@ page import="java.util.*" %> <jsp:useBean id="dbBean" scope="application" class="com.brainysoftware.burnaby.DbBean"/> <% String base = (String) application.getAttribute("base"); %> <TABLE CELLSPACING="0" CELLPADDING="5" WIDTH="150" BORDER="0"> <TR> <TD BGCOLOR="F6F6F6">

<FONT FACE="Verdana">Search</FONT> <FORM>

<INPUT TYPE="HIDDEN" NAME="action" VALUE="search"> <INPUT TYPE="TEXT" NAME="keyword" SIZE="10"> <INPUT type="SUBMIT" VALUE="Go"> </FORM> </TD>

</TR> <TR><TD BGCOLOR="F6F6F6"><FONT FACE="Verdana">Categories:</FONT></TD> </TR> <TR VALIGN="TOP"> <TD BGCOLOR="F6F6F6">

<% Hashtable categories = dbBean.getCategories(); Enumeration categoryIds = categories.keys(); while (categoryIds.hasMoreElements()) { Object categoryId = categoryIds.nextElement(); out.println("<A HREF=" + base + "?action=browseCatalog&categoryId=" + categoryId.toString() + ">" + categories.get(categoryId) + "</A><BR>"); } %> </TD> </TR> </TABLE>

Page 25: Java lezione 18

La home page<HTML> <HEAD> <TITLE>Welcome</TITLE> </HEAD> <BODY> <TABLE> <TR> <TD COLSPAN=2> <jsp:include page="Header.jsp" flush="true"/> </TD> </TR> <TR> <TD><jsp:include page="Menu.jsp" flush="true"/></TD> <TD VALIGN="TOP"> <H2>Welcome to Burnaby E-Mall.</H2> </TD> </TR> </TABLE> </BODY> </HTML>