MokaByte Numero 12 - Ottobre 1997
Foto
Java e CGI  
 
di
Maurizio Boscaini
 
Analisi del meccanismo di comunicazione CGI e 
delle comunicazione tra client e server Web offerte da Java 

 


 




In questo corso, vedremo come sia possibile creare pagine HTML dinamiche, tagliate a misura utente. In particolare, ci occuperemo del meccanismo di comunicazione CGI e alla possibilità di comunicazione tra client e server Web offerte da Java. Quindi, implementeremo i concetti visti, costruendo un programma in Java, che risolve una richiesta di ricerca in un database, restituendo all'utente una pagina HTML.
In queste lezioni, non esauriremo la teoria e la programmazione nel WWW, ma si cercherà di fornire le nozioni teorico-pratiche per costruire qualcosa di funzionante, che possa essere utilizzato come base per sviluppi più sofisticati.
Negli esempi, in particolare, faremo riferimento allo sviluppo in windows 95, ma il porting su altri sistemi non dovrebbe essere difficile.



 
 
 

Introduzione
Prima dell'avvento di Java, l'unico modo per avere pagine HTML non statiche, ma il cui contenuto fosse in qualche modo dinamico, era quello di servirsi delle famigerate CGI.
L'interfaccia CGI (Common Gateway Interface) è un metodo standardizzato per la comunicazione tra server e programmi residenti sul server HTTP (definiti script o programmi gateway o programmi CGI), scritti in C, PERL, Visual Basic, ..., e, come vedremo, anche in java su macchine, che, possedendo una JVM, siano in grado di interpretarli. L'interfaccia specifica, inoltre, una serie di variabili di ambiente, con informazioni quali: l'indirizzo del client remoto, la versione del software del server, o i parametri di un modulo da compilare. In questa maniera, si creano sequenze di immagini animate oppure pagine create in base ai dati inseriti in opportune maschere di input (FORM) presenti nelle pagine HTML. L'avvento di  Java ha spostato il processo di elaborazione dal server al client. Tuttavia, rimangono ancora buone ragioni per continuare ad utilizzare la classica programmazione server-side. Quest'ultima non ha bisogno di un browser java-enabled e risulta tuttora la più utilizzata per gestire la ricerca in database di Internet (dal momento che ragioni di dimensione e/o riservatezza limitano il dowload degli archivi o la loro interrogazione direttamente dal client).

La comunicazione tramite CGI
Schematicamente il procedimento CGI è il seguente:

Il meccanismo è quello di una normale comunicazione client-server, dove l'interfaccia di comunicazione è proprio quella CGI. Lo stesso procedimento avviene nelle normali richieste di pagine web, con l'unica differenza che in quest'ultimo caso pensa a tutto il server, che risponde al client inviando direttamente le pagine già pronte (in pratica: file HTML, GIF, JPG, ...).

Nella programmazione CGI, un URL viene richiesto da una directory riservata del server HTTP, spesso chiamata cgi-bin, dove risiedono i Web-eseguibili. Il server, tipicamente, inserisce informazioni aggiuntive alla pagina di HTML e agli altri formati di output generato dal programma. Per una generica pagina HTML il programma CGI produce un output di questo tipo:

Content-Type: text/html

<HTML>
<HEAD>...</HEAD>
<BODY>...</BODY>
</HTML>

(N.B. l'intestazione comprende due linee: la linea Content-Type specifica il tipo di dato ritornato in base alle specifiche MIME, la seconda linea è vuota e serve per separare l'header dai dati veri e propri)

Per quanto riguarda l'input del programma CGI (cioè del programma lanciato dal server) esistono due metodi di richiesta: GET e POST, vediamo in questa lezione le due varianti di GET, più avanti ci occuperemo di POST.

GET
Il server controlla se nell'URL è presente un carattere "?". Se sì, considera il file specificato dalla parte sinistra del "?" come il programma da eseguire e a cui passare i dati alla destra del "?". Una generica richiesta get assume il seguente aspetto:

    http://www.sito.it/cgi-bin/programma?dati
I parametri vengono passati in due modi, a seconda che dati contenga o meno un segno di uguale ("="). Nessun dato è accessibile al programma attraverso lo standard input (in realtà, di seguito consideriamo un webserver, che non si comporta così).

A. Senza "=" : Argomenti della linea di comando
I dati nell'URL sono separati dal segno "+" e gli argomenti risultanti sono passati al programma come argomenti della linea di comando.
Ad esempio,

     http://www.sito.it/cgi-bin/prova?qui+quo+qua
richiama il programma prova, nella directory cgi-bin del sito www.sito.it con i parametri qui, quo e qua.

B. Con "=" : Variabile di ambiente QUERY_STRING
Ora, l'intera stringa dati, dopo "?", viene posta nella variabile di ambiente QUERY_STRING, mentre il programma cgi-bin è richiamato senza argomenti.
 

Il server Web
Per mettere in pratica ciò che abbiamo appreso, oltre ad un normale ambiente di sviluppo java ed al browser (client), abbiamo bisogno di un server Web, cioè di un processo sempre in esecuzione, che risolva le richieste inoltrate attraverso il protocollo HTTP. Chi è già smaliziato con java può realizzarne uno proprio, gli altri possono cercare un server HTTP in rete (chi ha windows 95 può optare per OmniHTTPd, ottimo e semplice prodotto freeware scaricabile da uno dei mirror di  http://www.tucows.com , un sito dove è bello bivaccare col proprio brower, nella sezione server deamons).
Nell'installazione, l'eseguibile del server viene posto in una directory del nostro disco fisso, supponiamo C:\HTTPD, e vengono create alcune sottodirectory.
Con riferimento a OmniHTTPd (per gli altri la situazione è analoga) avremo:

 
C:\HTTPD\HTDOCS  per i documenti HTML
C:\HTTPD\CGI-BIN per i programmi CGI (eseguibili o programmi in PERL: .EXE e .PL)
C:\HTTPD\CGI-WIN per i programmi CGI specifici di windows (file batch .BAT, .EXE di Visual Basic, e . CLASS di java)

Il server Web si pone in ascolto di richieste alla porta 80 (porta di default per il protocollo HTTP), così che quando specificheremo un URL del tipo http://localhost/cgi-bin/test.exe  non "usciremo" dalla nostra macchina perchè la richiesta verrà soddisfatta al nostro deamon locale, che lancerà il file batch C:\HTTPD\CGI-BIN\TEST.EXE. Il suo output sarà la risposta per il browser.

(NOTA localhost corrisponde all'IP address 127.0.0.1 e identifica, nella suite di protocolli TCP/IP, la macchina locale, su cui gira il programma. In questa maniera, per testare il nostro lavoro non dobbiamo essere collegati alla rete)
 

Un esempio: ritorniamo un'immagine
Vediamo come ritornare da un programma CGI scritto in java (SendImage.java) un'immagine al browser. Poichè java è un linguaggio a bytecode, richiede un interprete per la sua esecuzione. Dovremo quindi scrivere un file batch (test.bat) per il lancio dell'interprete di SendImage.class. Nell'esempio, utilizziamo il metodo GET senza alcun parametro.
Prima di tutto, vediamo, il file test.html che contiene il link a test.bat.

<HTML>
<HEAD><TITLE>Prova CGI-Java - Metodo GET</TITLE></HEAD>
<BODY>
<B>Java e l'interfaccia CGI</B>
<P>Immagine:
<A HREF="http://localhost/cgi-win/test.bat">Logo di java</A>
</BODY>
</HTML>
I file test.bat e SendImage.class devono essere posti nella directory CGI-WIN, mentre test.html può essere messo in una directory qualsiasi.
Test.bat contiene il comando di disabilitazione dell'echo sullo standard output e la riga di comando per l'interprete java.
@echo off
java SendImage >> %3
NOTA OmniHTTPD quando richiama un programma gli passa come argomenti lo standard input (%1) e lo standard output (%3). Quindi, per scrivere sullo standard output, che è quello che ci interessa, dovremo redirezionare l'output di SendImage (>> %3).

Vediamo, finalmente, il sorgente SendImage.java. Come ho appena detto, ciò che scrivo sullo standard output (System.out) viene redirezionato al browser. E' sufficiente, dunque, inviare l'intestazione secondo le specifiche MIME e il file GIF.

 

import java.awt.*;
import java.io.*;

public class SendImage {

    public static void main(String args[]) {
        byte[] buf;

        // HEADER : il file è un immagine .GIF
        System.out.println("Content-type: image/gif");
        System.out.println();

        // DATI : apro il file dell'immagine e ne invio il contenuto allo standard output
        try {
            FileInputStream FIS = new FileInputStream("javalogo51x80.gif");
            buf = new byte[FIS.available()];
            FIS.read(buf,0,FIS.available());
            System.out.print(new String(buf,0));
            FIS.close();
        } catch (Exception e){System.out.println("errore : " + e);}
     }

} // end Image

A questo punto, nel browser, dopo aver richimato il nostro CGI-program, si dovrebbe vedere l'immagine col sottostante logo di java.


 

Conclusioni

Spero che questa puntata sia servita a diradare un po' della nebbia che avvolge il mondo mitico del CGI-program, mostrando che il nocciolo della questione è incentrato sul classico modello client/server. Nel futuro prossimo, descriveremo il metodo POST e esemplificheremo ulteriormente l'argomento dei CGI, in particolare, per quello che riguarda il passaggio dei parametri.
 
 
  

 

MokaByte rivista web su Java

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