Esempio di pagina in JSP
L'applicazione pratica con jsp che viene analizzata inseguito consiste nella creazione di un sondaggio, in cui gliutenti di un sito possono rispondere ad una domandascegliendo tra le risposte proposte ed eventualmentevisualizzare i risultati parziali delle votazioni. Come pertutti i sondaggi seri realizzati per un sito Internetè previsto il controllo del doppio voto, resoimpossibile dalla memorizzazione degli indirizzi ip degliutenti che votano. L'applicazione è costituita da4 file:
- sondaggio.htm, contenente il form da cui l'utente risponde alla domanda
- vota.jsp, che esegue la votazione proveniente dal form
- risultati.jsp, che visualizza i risultati parziali delle votazioni
- sondaggio.mdb, il database che gestisce tutto il sondaggio. Questo è costituito da due tabelle. La prima "frequenza" contiene un campo chiamato "risp" di tipo byte che indica il numero della risposta, e un campo "frequenze" di tipo intero che indica il numero di volte che si è votato per la rispettiva risposta. Nell'esempio, con 4 possibili risposte al sondaggio, la tabella è stata completata inserendo nelle prime 4 righe del campo "risp" i valori 0-1-2-3 e nel campo "frequenze" , ovviamente, i valori 0-0-0-0. La seconda tabella si chiama "ip_tab" e contiene in un campo "ip" di tipo testo la lista degli indirizzi ip di tutti gli utenti che hanno effettuato il voto. Vediamo nel dettaglio gli altri 3 file:
Sondaggio.htm
<html><head><title>Sondaggio</title></head><body><b><big>Domanda:</big></b><form action="vota.jsp"><input name="risposta" type="radio" value="0">Risposta 1<br><input name="risposta" type="radio" value="1">Risposta 2<br><input name="risposta" type="radio" value="2">Risposta 3<br><input name="risposta" type="radio" value="3">Risposta 4<br><input type="submit" value="vota"></form><a href="risultati.jsp">Visualizza i risultati parziali</a></font></body></html>
Vota.jsp
Questo file esegue in pratica la votazione, aggiornando ildatabase dopo aver fatto il controllo sull'ipdell'utente. Non deve essere necessariamente modificato.Al limite si possono personalizzare i messaggi di eseguita ofallita votazione.
<html><head><title>Sondaggio</title></head><body><font face="verdana" color="#3300ff" size="2"><% page errorPage = "PaginaErrore.jsp" %><%@ page language="java" import="java.sql.*" %><%Connection conn = null;//carica il file di classe del driverClass.forName("sun.jdbc.odbc.JdbcOdbcDriver");//crea la connessione con l'origine daticonn = DriverManager.getConnection("jdbc:odbc:sondaggio" ,"" ,"");//crea lo statementStatement st = conn.createStatement();//legge il parametro contenente la rispostaString preferenza = new String (request.getParameter("risposta"));String ip = new String(request.getRemoteAddr());ResultSet rs = st.executeQuery("SELECT ip from ip_tab WHERE ip LIKE '" +ip+ "'");if(!rs.next()){//l'ip non ha mai votato//esito dell'aggiormanento al Data baseint esito;//crea la tringa SQL per l'aggiornamentoString stringaSql = new String ("INSERT INTO ip_tab (ip) VALUES ('" +ip+ "')");st.executeUpdate(stringaSql);//crea la stringa SQL per l'aggiornamentostringaSql = "UPDATE frequenze SET frequenza=frequenza+1 WHERE risp LIKE '" +preferenza+ "'";esito = st.executeUpdate(stringaSql);//controlla che tutto sia andato beneif (esito==1)out.println("Votazione eseguita con successo");elseout.println("Errore, non stato possibile eseguire la votazione");}//ifelse{ //l'utente ha gia votatoout.println("Spiacenti, hai già votato!<br>");out.println("Per ragioni di credibilità del sondaggio<br>");out.println("ogni visitatore può votare una sola volta<br><br>");}//elsest.close();conn.close();%><br><br><a href="risultati.jsp">Visualizza i risultati parziali</a></font></body></html>
Risultati.jsp
Questo è il file che esegue il compito piùcomplicato. Deve estrarre dal database il numero di utentiche hanno votato in totale e per ogni singola risposta,calcolare la percentuale e stampare una breve tabella diriepilogo e un grafico che riassume visivamentel'andamento del sondaggio. Nel file appena visto deveessere modificato il numero di possibili risposte (riga 20) eil valore delle stringhe contenenti le risposte (righe25-28). Tutto il resto del codice può rimanereinvariato.
<html><head><title>Risultati del sondaggio</title></head><body bgcolor=#FFFF99><center><b><big>Domanda del sondaggio</b></big><br><br><% page errorPage = "PaginaErrore.jsp" %><%@ page language="java" import="java.sql.*" %><%Connection conn = null;//carica il file di classe del driverClass.forName("sun.jdbc.odbc.JdbcOdbcDriver");//crea la connessione con l'origine daticonn = DriverManager.getConnection("jdbc:odbc:sondaggio" ,"" ,"");//crea lo statementStatement st = conn.createStatement();/* --- DEFINIZIONE DI VARIABILI --- */int numRisp = 4; //numero possibili risposteint votiTot; //numero totale dei votifloat percentuale; //percentuale per ogni rispostaint frequenze[] = new int[numRisp]; //numero di voti per ogni rispostaString risposte[] = new String[numRisp]; //array di stringhe con le risposterisposte[0]="Risposta 1";risposte[1]="Risposta 2";risposte[2]="Risposta 3";risposte[3]="Risposta 4";//crea il recordset -> calcolo dei voti totaliResultSet rs = st.executeQuery("SELECT sum(frequenza) as tot fromfrequenze");rs.next();votiTot = rs.getInt("tot");out.println("Totale dei voti: " +votiTot+ "<br>");//calcolo dei voti per ogni singola risposta e stampafor (int i=0; i<numRisp; i++){rs=st.executeQuery("SELECT sum(frequenza) as tot from frequenze WHERErisp = " +i);rs.next();frequenze[i]=rs.getInt("tot");out.println(risposte[i]+ ": " +frequenze[i]+ " voti<br>");}//for%><br><br><table align=center border=0><%//creazione del grafico dei votifor (int i=0; i<numRisp; i++){//calcolo della percentualepercentuale = (float)frequenze[i]/votiTot*100;out.println("<tr valign='center' align='left'><td>");out.println(risposte[i]+ "</td><td>");out.println("<img src='blu.gif' width=" +percentuale*5+ " height=20>");out.println((int)percentuale+ "%</td>");}//for%></tr></table><%st.close();rs.close();conn.close();%></body></html>
Le JSP sono state create anche per facilitarel'implementazione di servizi di commercio elettronico, inrapida via di sviluppo soprattutto di questi tempi.
Il più delle volte per comprare un qualsiasi tipo dioggetto sul web, si utilizza utilizzato quello che vienechiamato carrello della spesa elettronico, che permette dimemorizzare gli oggetti che si intende acquistare edeventualmente annullarne l'ordinazione.
Come esempio si è supposto di dover creare un carrellodella spesa per un negozio di CD musicali.
Il progetto che implementa tale servizio è formato datre file:
- Carrello.jsp: rappresenta il catalogo dei CD disponibili, con la possibilità di ordinazione;
- visCarr.jsp: visualizza il contenuto attuale del carrello, permettendo l'annullamento di un eventuale acquisto;
- Carrello.java: bean che contiene tutte le funzioni di memorizzazione, eliminazione e quant'altro, utili allo sviluppo delle pagine JSP.
Per prima cosa è necessario esaminare il bean,affinché risultino chiare le funzioni utilizzate poinelle due JSP.
//Carrello.java import java.lang.String;import java.lang.Integer;import java.lang.Float;import java.util.Hashtable;import java.util.Enumeration;public class Carrello{//variabile di tipo Hashtable utilizzata per memorizzare gli elementi presenti nel carrelloprotected Hashtable cd = new Hashtable();//varibile intera utilizzata per la memorizzazione del numero di CD attualmente nel carrelloprivate int numCd; //costruttorepublic Carrello() {numCd=0;}//Carrello//metodo per ottenere il numero di CD attualmente nel carrellopublic int totCD(){return numCd;}//numCD// Inserimento di cd nel carrello// I: id: indice chiave di identificazione del CD// art: nome dell'artista// tit: titolo dell'album// prezzo: prezzo del CDpublic void aggiungiCd (String id, String art, String tit, float prezzo){ //inserimento in un vettore di stringhe degli attributi del CD appena inserito nel carrello//img/guide/30/img/guide/30/img/guide/30/img/guide/30/è inserito inoltre il numero di CD di quel tipo ordinatiString[] dati_cd= {art, tit, Float.toString(prezzo) , "1" , id};numCd++;//se il CD è non già stato ordinatoif (!cd.containsKey(id)){//inserisci il CD nel carrellocd.put(id, dati_cd);}//if//altrimentielse {//incrementa il numero di CD di quel tipo ordinatiint tmp;String[] datiTemp = (String[])cd.get(id);tmp = Integer.parseInt(datiTemp[3]);tmp++;datiTemp[3]=Integer.toString(tmp);cd.put(id, datiTemp);}//else}//aggiungiCd //Metodo di rimozione dal carrello di un CD//I: id: indice del CD da rimuoverepublic void rimuoviCd (String id){//se il CD è presente nel carrelloif (cd.containsKey(id)) {//decrementa il numero di CDnumCd--;String[] temp = (String[])cd.get(id);//se il CD è presente in copia singolaif (Integer.parseInt(temp[3]) == 1)//elimina il CD dal carrellocd.remove(id);//altrimentielse {//decrementa il numero di copie di quel CD ordinateint tmp = 0;String[] datiTemp = (String[])cd.get(id);tmp = Integer.parseInt(datiTemp[3]);tmp--;datiTemp[3]=Integer.toString(tmp);cd.put(id, datiTemp);}//else}//if}//rimuoviCd //Metodo per la creazione di un oggetto Enumeration utilizzato per scorrere velocemente//gli elementi nel carrellopublic Enumeration enum() {return cd.elements();}//enum//Metodo che restituisce il prezzo totale dei CD inseriti nel carrello fino adessopublic float spesaTot(){float tot = 0.00f;String[] temp;//crea l'oggetto EnumerationEnumeration i = this.enum();//finchè ci sono elementi nel carrellowhile (i.hasMoreElements()){temp = (String[])i.nextElement();//incrementa la spesa totale del prezzo del CD correntetot += (Float.parseFloat(temp[2]) * Integer.parseInt(temp[3]));}//whilereturn tot;}//spesaTot//Metodo che restituisce il prezzo di un CD moltiplicato per il numero delle copie ordinate//I: id:indice del CDpublic float prezzo(String id){String[] temp;float tmp=0.0f;temp = (String[])cd.get(id);tmp = Float.parseFloat(temp[2]) * Integer.parseInt(temp[3]);return tmp;}//prezzo
E' interessante notare come la classe Hashtable rendafacile memorizzare e accedere alle informazioni, rendendoleper certi aspetti molto simili ad un database. Infatti,suddetta classe (contenuta nel package java.util e derivatadalla classe astratta Dictionary) permette di memorizzare unacollezione di oggetti (più specificatamente dellecoppie oggetto-chiave) avente funzioni molto simili aidatabase: le chiavi non replicabili permettono infatti unveloce accesso ai dati.Sia le chiavi che gli oggetti devonoessere di tipo Object.
I metodi più importanti implementati da Hashtablesono:
- hashtable.size(): restituisce un intero contenente il numero di elementi inseriti in hashtable;
- hashtable.isEmpty (): restituisce un valore booleano che indica se il dizionario è vuoto o meno (il valore true segnala il dizionario vuoto);
- hashtable.get (Object chiave): restituisce l'oggetto a cui è associata la chiave chiave, se la chiave non viene trovata restituisce null;hashtable.put (Object chiave, Object elemento): inserisce in hashtable l'elemento elemento e gli associa la chiave chiave, se chiave è già stata inserita viene sostituito l'oggetto a lei associato e viene restituito, altrimenti viene restituito null;
- hashtable.remove (Object chiave): rimuove da hashtable l'elemento associato a chiave, se la chiave non esiste viene restituito null.
Ad un oggetto di tipo Hashtable può venire associatoun oggetto di tipo Enumeration, che permette di scorrere lacollezione di oggetti, utilizzando i metodi:
enumeration.hasMoreElements (): che restituisce il valorebooleano true se ci sono ancora elementi da scorrere;
- enumeration.nextEle(): si sposta all'elemento successivo.
Grazie alla creazione di questo bean la pagina Carrello.jsp(qui di seguito) presenta un buon incapsulamento del codice,facilitando sia l'interpretazione (è fattoprevalentemente a codice HTML) che la modifica.
<!-- Carrello.jsp --> <HTML> <HEAD><TITLE>Vendita CD On-line</TITLE></HEAD> <BODY BGCOLOR="#33CCCC" text="#000099" vlink="#990099" alink="#000099"> <!-istanziazione del bean Carrello.jsp, con ambito session --><jsp:useBean id="car" scope="session" class="Carrello" /img/guide/30/img/guide/30/img/guide/30/img/guide/30/> <%String id = request.getParameter("id");//se è stato aggiunto un CD al carrelloif (id != null){//acquisisci i dati del CDString artista=request.getParameter("artista");String titolo=request.getParameter("titolo");float prezzo = Float.parseFloat(request.getParameter("prezzo"));//e aggiungilo al carrellocar.aggiungiCd (id, artista, titolo, prezzo);}//if%> <font face="Verdana" size="6"><center>CATALOGO COMPACT DISC A DISPOSIZIONE <br><br></center></font> <font face="Verdana"><a href="visCarr.jsp"> Quantità attualmente nel carrello: </a> <%= car.totCD();%><br><br><center><table width="60%" border="1" align="center" bordercolorlight="#990099" bordercolordark="#990099"><tr><th>Artista</th><th>Titolo</th><th>Prezzo</th></tr><tr><form action="Carrello.jsp" method="post"><td>Dream Theater</td><td>Awake</td><td>L.25000</td><td><center><input type="submit" name="add" name="acquista" value="Aggiungi alcarrello"></center></td><input type="hidden" name="id" value="1"><input type="hidden" name="artista" value="Dream Theater"><input type="hidden" name="titolo" value="Awake"><input type="hidden" name="prezzo" value="25000"></form><td></tr><tr><form action="Carrello.jsp" method="post"><td>Iced Earth</td><td>The Dark Saga</td><td>L.35000</td><td><center><input type="submit" name="add" name="acquista" value="Aggiungi alcarrello"></center></td><input type="hidden" name="id" value="2"><input type="hidden" name="artista" value="Iced Earth"><input type="hidden" name="titolo" value="The Dark Saga"><input type="hidden" name="prezzo" value="35000"></form><td></tr><tr><form action="Carrello.jsp" method="post"><td>Queen</td><td>Innuendo</td><td>L.35000</td><td><center><input type="submit" name="add" name="acquista" value="Aggiungi alcarrello"></center></td><input type="hidden" name="id" value="3"><input type="hidden" name="artista" value="Queen"><input type="hidden" name="titolo" value="Innuendo"><input type="hidden" name="prezzo" value="35000"></form><td></tr></table></font></center></BODY></HTML>
Infine vediamo il codice di visCar.jsp:
<!-- visCarr.jsp --><!-- inclusione dei package per l'utilizzo di alcune funzioni standard --><%@ page import="java.util.*" %><%@ page import="java.lang.*" %><!-- istanziazione del bean Carrello.jsp con ambito session --><jsp:useBean id="car" scope="session" class="Carrello" /img/guide/30/img/guide/30/img/guide/30/img/guide/30/><HTML><HEAD><TITLE>Carrello della spesa</TITLE></HEAD><BODY BGCOLOR="#33CCCC" text="#000099" vlink="#990099" alink="#000099"><%String idtmp = request.getParameter("id");//se è stato eliminato un CD dal carelloif (idtmp != null){car.rimuoviCd(idtmp);}//if%><font face="Verdana" size="6"><center>CARRELLO</center></font><br><br><font face="Verdana">Quantità attualmente nel carrello: <%= car.totCD();%><br><br><center><table width="60%" border="1" align="center" bordercolorlight="#990099" bordercolordark="#990099"><tr><th>Artista</th><th>Titolo</th><th>Prezzo (L.)</th><th>Quantità</th></tr><%//creazione di un oggetto EnumerationEnumeration ogg = car.enum();String[] temp;//finchè ci sono elementi nel carrellowhile (ogg.hasMoreElements()){temp= (String[])ogg.nextElement();%><tr><td><%= temp[0] %></td><td><%= temp[1] %></td><td>L.<%= car.prezzo(temp[4])%></td><td><center><%= Integer.parseInt(temp[3]) %></center></td><td><center><form action="visCarr.jsp" method="post"><input type="submit" name="rem"name="togli" value="Togli"></center></td><input type="hidden" name="id" value= <%= temp[4]%>></form><td></tr><%}//while%><tr><td></td><td>Tot</td><td>L.<%= car.spesaTot()%></td><td><center><%= car.totCD()%></center></td></tr></table><font size="2">[ <a href="Carrello.jsp">Indietro</a> ]</font></center></BODY></HTML>
In questo caso è stata utilizzata la direttiva page(spiegata precedentemente) affinché venissero inclusinella pagina alcuni package di utilità.