MokaByte Numero 14 - Dicembre 1997
Foto
Java e CGI

 

di
Maurizio Boscaini
 terza puntata 

 


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.
 

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:
 



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
  

 

MokaByte rivista web su Java

MokaByte ricerca nuovi collaboratori
Chi volesse mettersi in contatto con noi può farlo scrivendo a mokainfo@mokabyte.it