Introduzione alla lezione

In questa terza e ultima puntata, vedremo come interagire con un database attraverso interrogazione effettuate in Java.

Interrogazione di un database

Il nostro obiettivo, dunque, è quello di interrogare da una pagina HTML un database residente sul server web tramite un programma Java, che ritorna una pagina HTML di risposta in base ai dati rinvenuti.

Il procedimento è simile a quello della volta scorsa, con la differenza che ora passeremo dei parametri dalla pagina HTML al programma Java per specificare la query per il database.

Abbiamo bisogno dei seguenti file:

Pagina HTML iniziale dbtest.html File batch dbtest.bat Programma principale Java per l'interrogazione e la risposta Db.java Programma Java di supporto Cgi.java database rubrica.mdb

Prima di tutto, vediamo, il file dbtest.html che contiene il link a dbtest.bat e che può essere posto in una qualunque directory. Il link è contenuto in una FORM HTML, poichè questo TAG (marcatore del linguaggio) ci permette di specificare dei parametri da passare al programma CGI e visualizza pulsanti e campi di testo. Nel nostro caso, passiamo solo il parametro di nome RECORD e con valore 1, per specificare che il record che vogliamo visualizzare è il primo

> \<HTML\>

> \<HEAD\>

> \<TITLE\>Esempio: database test\</TITLE\>

> \</HEAD\>

> \<BODY TEXT="#FFFFFF" background="smgreen.gif" LINK="#FF0000" VLINK="#551A8B" ALINK="#FF0000"\>

> Per consultare il database clickare qui

> \<FORM NAME="myform" METHOD="POST" ACTION="http://localhost/cgi-win/dbtest.bat"\>

> \<INPUT TYPE=HIDDEN NAME="RECORD" VALUE="1"\>

> \<INPUT TYPE=SUBMIT VALUE="Interrogazione database"\>

> \</FORM\>

> \</BODY\>

> \</HTML\>

Notiamo che utilizziamo per il tag INPUT il tipo HIDDEN. Infatti, il tipo di input nascosto permette di passare in maniera invisibile all'utente, se non nel sorgente HTML stesso, dei parametri dalla pagina HTML al server HTTP.

Figura 1
Figura 1

Il file dbtest.bat deve essere posto nella directory CGI-WIN. Anche in questo esempio il compito del batch file si riduce alla disabilitazione dell'echo sullo standard output e al richiamo dell'interprete Java per il nostro file .java. Volendo passare anche dei valori al programma, è necessario specificare che il canale %1 va impostato a standard input.

> @echo off

> java Db \<\< %1 \>\> %3

>

Il database rubrica.mdb è un semplicissimo database di MS-Access 97, che contiene la sola tabella "elenco" e un paio di record. Ricordo che perchè sia raggiungibile dal ponte JDBC-ODBC è necessario registrarlo nell'ODBC server, accessibile dal pannello di controllo. L'adattamento a altri RDBMS o ad altre piattaforme può essere visto nella documentazione Sun.

Il file cgi.java è stato visto nella puntata precedente.

La classe db.java prende le informazioni, le formatta e le direzione sullo standard output (System.out).Da notare l'utilizzo di alcuni metodi privati di supporto (send, sendln, sendbr, sendSpace), che rendono più leggibile e semplice il sorgente. Il meccanismo è abbastanza semplice (rimando ai numerosi articoli sull'argomento pubblicati su MokaByte): si tratta di aprire una connessione con un database utilizzando il bridge jdbc-odbc ed effettuare le opportune interrogazioni.

import
java.sql.*;

public
class Db {

   
private Cgi  cgi; // rappresenta i parametri CGI

   
private int  index;

   
private String url = new String("rubrica"); // nome del database

   
private Connection connection;

 

   
public Db() {

       
// inizializzo l'ambiente CGI

       
cgi = new Cgi(System.in);

       
// HEADER

       
sendln("Content-type: text/html");

       
sendln("");

       
// CONTENT

       
index = Integer.parseInt(cgi.getProperty("RECORD"));

       
sendln("<HTML>");

       
send("<BODY BACKGROUND=\""+ getBaseReferer() +"/smgreen.gif\"");

       
sendln(" TEXT=#FFFFFF LINK=#0000EE VLINK=#551A8B ALINK=#FF0000>");

       
sendln("<B>DATABASE</B><HR>");

       
boolean errore = false;

       
try {

           
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");

           
connection = DriverManager.getConnection("jdbc:odbc:" + url);

       
} catch(Exception e ) {

           
System.out.println("ERRORE : "+ e);

           
errore = true;

       
} // end try

       
try {

           
if (!errore) {

               
createMask();

           
} else {

               
sendln("errore...");

           
}

           
// chiudo la connessione col database

           
connection.close();

       
} catch(Exception e){

       
System.out.println("ERRORE : "+ e);

       
} // end try

       
sendln("</BODY></HTML>");

   
} // end Db()

 

   
private void createMask() throws SQLException {

       
Statement statement = connection.createStatement();

       
String sql="SELECT * FROM elenco Where IDElenco="+ index;

       
ResultSet res = statement.executeQuery(sql);

       
if (res.next()){

       
send("<FORM NAME=form>");

      
send("<INPUT TYPE=HIDDEN NAME=RECORD VALUE="+ (index+1) +">");

      
sendbr("<INPUT TYPE=TEXTFIELD VALUE="+ res.getInt(1) +">");

      
send("<INPUT TYPE=TEXTFIELD VALUE="+ res.getString(2) +">");

      
sendbr("<INPUT TYPE=TEXTFIELD VALUE="+ res.getString(3) +">");

      
send("<INPUT TYPE=TEXTFIELD VALUE="+ res.getString(4) +">");

      
send("<INPUT TYPE=TEXTFIELD VALUE="+ res.getString(5) +">");

      
sendbr("<INPUT TYPE=TEXTFIELD VALUE="+ res.getString(6) +">");

      
send("<INPUT TYPE=TEXTFIELD VALUE="+ res.getString(7) +">");

      
sendbr("");

      
send("</FORM>");

      
if (index > 1) {

           
sendln("<FORM NAME=precform METHOD=POST ACTION=http://localhost/cgi-win/dbtest.bat>");

           
sendln("<INPUT TYPE=SUBMIT VALUE=PRECEDENTE>");

           
sendln("<INPUT TYPE=HIDDEN NAME=RECORD VALUE="+ (index - 1) +">");

           
sendln("</FORM>");

      
}

      
sendln("<FORM NAME=nextform METHOD=POST                
ACTION=http://localhost/cgi-win/dbtest.bat>");

      
sendln("<INPUT TYPE=SUBMIT VALUE=SUCCESSIVO>");

      
sendln("<INPUT TYPE=HIDDEN NAME=RECORD VALUE="+ (index + 1) +">");

      
sendln("</FORM>");

     
} // end if

 }
// end createMask()

 

 private
String getBaseReferer() {

 
String referer = cgi.getProperty("Referer");

 
int lastSlashIndex = referer.lastIndexOf("/");

 
return referer.substring(0, lastSlashIndex);

 }
// end getBaseReferer()

 

 private
void send(String string) {

 
System.out.print(string);

 }
// end send()

 

 private
void sendln(String string) {

 
System.out.println(string);

 }
// end sendln()

 

 private
void sendbr(String string) {

 
System.out.println(string +"<BR>");

 }
// end sendln()

 

 private
void sendSpace(int numberOfSpace) {

 
String str = new String("");

 
for(int i = 0; i < numberOfSpace; i++) {

  
str += " ";

 
}

 
System.out.println("<PRE>"+ str +"</PRE>");

 }
// end sendSpace()

 

   
public static void main(String args[]) {

    
new Db();

 }
// end main()

} /* end
class Db */

A questo punto, nel browser, dopo aver richiamato il nostro CGI-program, si dovrebbe vedere, purtroppo dopo una quindicina di secondi, l'output seguente:

Figura 2
Figura 2

Conclusioni

Terminiamo con questo articolo il nostro mini corso sull'utilizzo di Java per scrivere programmi-cgi, che possano essere su un server web e richiamati da pagine HTML. L'esercizio di questo mese, già piuttosto complesso, è passibile di numerosi miglioramenti (ad esempio passando come parametro l'URL dello sfondo, oppure effettuando un controllo sull'ultimo record), ma costituisce un prototipo funzionante di comunicazione client-server e di accesso a db. Spero che questi esempi abbiano reso il meccanismo CGI un po' più "common" ai nostri lettori.

Buon lavoro a tutti,

Maurizio