Newsgroup: it.comp.java
Titolo: Domanda su comunicazione tra Pagina HTML e servlet

Ciao,
Vorrei cercare, se possibile naturalmente, di risolvere il seguente
problema:
Sulla pagina HTML poniamo di avere un bottone ed una Text; alla
pressione del bottone (ma nulla vieta di essere un link ad esempio),
mi piacerebbe che invece di effettuare il post verso il servelet e
cambiare pagina con il dato caricato nella text, avvenga che la
servlet risponda alla chiamata ritornando un messaggio, cioè che io
possa in realtà chiamare un metodo sulla servlet il quale ritorni una
stringa, che poi possa venire trasferita nel value della text, o in un
qualunque altro posto.
ESEMPIO:
<HTML>
<HEAD>
  <Script language="Javascript">
     function reperisciMessaggio () {
        testo.value= NomeServlet.metodoServlet (listaParametri);
     }
  </SCRIPT> 
</HEAD>
<BODY>
  <input type=text id="testo">
  <input type=button id="bottone" value="premi"
onClick="reperisciMessaggio();">
</BODY>
</HTML>
Spero di non avervi fatto ridere troppo.

possa in realtŕ chiamare un metodo sulla servlet il quale ritorni una


 wrote:

|
| Bruno Bossola
| A Java Software Engineer :-)
| 
http://bbruno.fasturl.it
|
| 
http://members.xoom.it/bbruno
| 
http://digilander.iol.it/bbossola
|


La soluzione dell'applet mi sembra affascinante;
ti va di illustrarmi come mettere inpiedi questo tipo di gioco
(sopratutto all'interno dell'applet)?
credo che il JavaScript debba richiedere un metodo all'applet il quale
fa l'operazione (??? qua mi manca il pezzo).
Ci sarebbero problemi di certificazione dell'applet in questo
specifico caso??
l'applet "peserebbe" parecchio?
attendo freneticamente una tua risposta.
grazie

attendo freneticamente una tua risposta.
Eccola! Allora io attendo freneticamente altre tue domande :-D
Ciao,
    Bruno.


|


Grazie bruno per l'esauriente spiegazione, però mi sfugge una
piccolissima ma forse sostanziale cosa... non mi hai fatto vedere come
chiamare poi all'interno dell'applet un metodo, action di un servlet;
Ed è li fondamentalmente il mio problema;
O in realtà mi stai facendo intuire che per utilizzare il tutto sempre
tramite il tuo GMI debbo passare?
ciao e grazie delle spiegazioni fin qui date;



Allora, sostanzialmente i problemi sono due
1. fare dialogare l'applet e i componenti della pagina HTML
2. fare dialogare l'applet con la servlet.
La mia risposta si concentra sul punto 1, come hai giustamente rilevato, perche' pensavo
che quello fosse il punto che ti mancava. Comunque, nessun problema, passiamo al 2.
Allora, per fare dialogare applet e servlet e' necessario che l'applet faccia
(tipicamente) delle POST HTTP verso la servlet, "trasportando" sullo stream di richiesta i
dati necessari ad effettuare l'operazione e ricevendo sullo stream di risposta il flusso
di dati ottenuti dall'operazione effettuata in remoto. La servlet deve essere realizzata
ad-hoc ovviamente (il suo metodo doPost() deve gestire questa comunicazione) e inoltre un
protocollo di comunicazione deve essere realizzato: di solito si parte semplicemente
scambiando delle semplici stringhe, fino ad avere protocolli sempre + evoluti che di norma
si basano sul meccanismo di serializzazione offerto da Java.
Se chiedi a me come farei a realizzare questa comunicazione, beh, io ovviamente userei il
mio GMI che fa esattamente questo, ed è anche semplicissimo da usare, rispetto a fare
tutto da zero. Il meccanismo e' simile a quello di RMI: tu definisci un'interfaccia in cui
dichiari i metodi che vuoi eseguire in remoto, quindi scrivi un'implementazione di tali
metodi e mediante un compilatore generi automaticamente (beh, qui sta il bello!) la
servlet e un oggettino, un proxy, che usi sull'applet in vece della vera implementazione,
che invece depositi in remoto. 
Come fare? Supponiamo che tu abbia installato correttamente il JDK: ecco un mini-tutorial
passo passo! 
Ah, ovviamente prima devi scaricarti la distribuzione di GMI che trovi sul mio sito!
http://members.xoom.it/bbruno/gmi.html
1. Installare GMI per la compilazione 
-------------------------------------
Okay, procedo prima di tutto a scompattare la distribuzione di GMI in una directory, ad
esempio sotto c:\apps\gmi. Per compilare mi serve che nel CLASSPATH ci siano anche le
classi di GMI, che si trovano sotto \bin nella distribuzione, e anche qualche altra
libreria. Qui sotto lo faccio passo passo:
  set CLASSPATH=.
  set CLASSPATH=%CLASSPATH%;c:\programmi\jsdk2.2\lib\servlet.jar
  set CLASSPATH=%CLASSPATH%;c:\programmi\jdk1.3\lib\tools.jar
  set CLASSPATH=%CLASSPATH%;c:\apps\gmi\bin
Okay, per ordine, ho incluso:
  - la directory corrente (.) 
  - il jar contenente le servlet API
  - il particolare JAR del JDK che contiene il compilatore java e che viene
    usato quando compili con GMI
  - la directory bin di GMI (che contiene le classi di GMI)
Ora se invoco il compilatore GMIC digitando:
  java com.gmi.Gmic
Ottendo il seguente output:
  GMIC - GMI Compiler (Bruno Bossola) - version 0.21a, 4 Apr 2001
  Error: Nessun target specificato
  ...
Okay, GMI e' pronto per la compilazione.
2. Generare servlet e proxy con GMI 
-----------------------------------
Allora, permettimi un esempio idiota :-): facciamo finta che la funzione che ci serve
avere in remoto sia una funzione che si occupa di fare la somma o la moltiplicazione di
due numeri (difficile, eh?).
Spostiamoci sotto la directory del progetto, ad esempio c:\progetti\operazioni e creiamo i
file necessari a creare la nostra applicazione. L'interfaccia Java sara' qualcosa di
simile:
--- File Operazioni.java
public interface Operazioni 
{
    public double somma(double valore1, double valore2)
    ;
    public double moltiplicazione(double valore1, double valore2)
    ;
}
L'implementazione segue a ruota:
--- File OperazioniImpl.java
public class OperazioniImpl implements Operazioni 
{
    public double somma(double valore1, double valore2)
    {
        return valore1+valore2;
    }
    public double moltiplicazione(double valore1, double valore2)
    {
        return valore1*valore2;
    }
}
Okay, ora compiliamo i file.
  javac *.java
Perfetto, a me compila. Adesso dobbiamo, mediante il compilatore di GMI, GMIC, generare il
proxy e la servlet per il nostro sistema: e' molto semplice, e' sufficiente invocare il
compilatore specificandogli l'interfaccia:
  java com.gmi.Gmic Operazioni
L'output che ottengo e' questo:
  GMIC - GMI Compiler (Bruno Bossola) - version 0.21a, 4 Apr 2001
  [gmic] Generating OperazioniServlet.java [ok]
  [gmic] Compiling  OperazioniServlet.java [ok]
  [gmic] Generating OperazioniProxy.java [ok]
  [gmic] Compiling  OperazioniProxy.java [ok]
Perfetto, la compilazione e' andata bene! (almeno a me!) 
Ora nella tua directory dovrebbero esserci questi file:
   Directory di c:\progetti\operazioni
  15/11/2001  09.50       <DIR>          .
  15/11/2001  09.50       <DIR>          ..
  15/11/2001  09.35                  151 Operazioni.class
  15/11/2001  09.33                  174 Operazioni.java
  15/11/2001  09.35                  338 OperazioniImpl.class
  15/11/2001  09.35                  276 OperazioniImpl.java
  15/11/2001  09.58                2.541 OperazioniProxy.class
  15/11/2001  09.58                4.086 OperazioniProxy.java
  15/11/2001  09.58                1.932 OperazioniServlet.class
  15/11/2001  09.58                2.262 OperazioniServlet.java
Come vedi il compilatore ha generato due nuove classi, OperazioniProxy e
OperazioniServlet. Ora, a noi non interessa sapere cosa contengano questi file. e'
sufficiente che poi le utilizziamo per gestire la comunicazione.
3. Installare le servlet sotto Tomcat
-------------------------------------
Okay, qui uso tomcat perche' e' quello normalmente piu' utilizzato. Allora, supponendo che
tu abbia installato tomcat sotto c:\programmi\tomcat, creiamoci la directories per il
nostro progetto. Dobbiamo creare la struttura del progetto:
  md c:\programmi\tomcat\webapps\operazioni
  md c:\programmi\tomcat\webapps\operazioni\html
  md c:\programmi\tomcat\webapps\operazioni\Web-inf
  md c:\programmi\tomcat\webapps\operazioni\Web-inf\classes
Okay, ora copiamo sotto ...\operazioni\Web-inf\classes tutte le classi di GMI:
  xcopy /s c:\apps\gmi\bin\*.class c:\programmi\tomcat\webapps\operazioni\Web-inf\classes
In realta' non ti servono proprio *tutte* le classi, ma semplifichiamo. Nota ad esempio
che questo ti copiera' anche un package \boo (!) che e' solo un esempio di uso di GMI, e
che potrai poi rimuovere.
Okay, ora copiamo sempre sotto ...\operazioni\Web-inf\classes tutte le classi del progetto
che devono stare sul server, ovvero la servlet, l'interfaccia e l'implementazione
dell'interfaccia
  copy c:\progetti\operazioni\OperazioniServlet.class
c:\programmi\tomcat\webapps\operazioni\Web-inf\classes
  copy c:\progetti\operazioni\Operazioni.class
c:\programmi\tomcat\webapps\operazioni\Web-inf\classes
  copy c:\progetti\operazioni\OperazioniImpl.class
c:\programmi\tomcat\webapps\operazioni\Web-inf\classes
Fatto? Perfetto, avvia tomcat (o riavvialo) e prova ad accedere con un browser a questo
URL:
http://localhost:8080/operazioni/servlet/OperazioniServlet
Perfect! A me risponde una pagina HTML di questo tipo:
 Operazioni status page
 Status page of servlet Operazioni at time Thu Nov 15 10:22:30 CET 2001 
 Started at Thu Nov 15 10:22:30 CET 2001 
 
 Total number of call until now: 0 
 
 User agents: 
 
 Memory status 
 Free memory: 1282696 
 Total memory: 2031616 
Questo significa che la servlet e' installata e funzionante!
4. Preparare l'applet
---------------------
Okay, ora prepariamo il nostro applet. Sempre di un esempio si tratta, e quindi mi limito
veramente al minimo indispensabile! (ed e' pure brutto :-D)
import java.net.*;
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
public class OperazioniApplet extends Applet implements ActionListener		
{
    private TextArea itsOutput = new TextArea();
 
    public void init()
    {
        setLayout(new BorderLayout());
 
        Panel southPanel = new Panel(new FlowLayout(FlowLayout.CENTER));
        Button b = new Button("Invoke!");
        b.addActionListener(this);
        southPanel.add(b);
 
        add(BorderLayout.CENTER, itsOutput);
        add(BorderLayout.SOUTH,  southPanel);
    }
 
    public void actionPerformed(ActionEvent e)
    {
        double val1 = 17;
        double val2 = 13;
        double res;
 
        try
        {
            itsOutput.setText("Operazione in corso...\n\n");
 
            URL servletBaseAddress = new URL
                (
                    getCodeBase().getProtocol(),
                    getCodeBase().getHost(),
                    getCodeBase().getPort(),
                    "/operazioni/servlet/"
                );
 
            Operazioni operazioni = new OperazioniProxy(servletBaseAddress);
 
            itsOutput.append("La somma "+val1+" e "+val2+" e'... ");
            res = operazioni.somma(val1,val2);
            itsOutput.append(res+"!\n");
 
            itsOutput.append("Il prodotto "+val1+" e "+val2+" e'... ");
            res = operazioni.moltiplicazione(val1,val2);
            itsOutput.append(res+"!\n");
        }
        catch (Throwable ex)
        {
            itsOutput.append("Eccezione: "+ex.getClass().getName()+"\n");
            itsOutput.append(ex.getMessage()+"\n");
            ex.printStackTrace();
        }
        finally
        {
            itsOutput.append("\nFatto!");
        }
    }
}
Nota che l'applet ottiene un reference ad un oggetto di tipo Operazioni semplicemente
istanziando OperazioniProxy, che puoi vedere come una versione "locale" dell'oggetto che
sta sul server.
Prepariamo anche il file Operazioni.html che conterra' l'applet:
<HTML>
<BODY>	
	<APPLET CODE="OperazioniApplet.class"  WIDTH=600 HEIGHT=300>
	</APPLET>
</BODY>
</HTML>
Okay, compilimo l'applet:
  javac OperazioniApplet.java
Funge!
5. Installare l'applet
----------------------
Okay, prendiamo sempre come ambiente quello che abbiamo creato su Tomcat, che usiamo anche
da web server. Quello che dobbiamo fare ora e' copiare sul web server le classi necessarie
a fare funzionare l'applet. Cominciamo da quelle dell'applet:
  copy OperazioniApplet.class c:\programmi\tomcat\webapps\operazioni\html
  copy Operazioni.class       c:\programmi\tomcat\webapps\operazioni\html
  copy OperazioniProxy.class  c:\programmi\tomcat\webapps\operazioni\html
E non dimentichiamoci il file html:
  copy Operazioni.html        c:\programmi\tomcat\webapps\operazioni\html
Okay, ora dobbiamo copiare le classi necessarie di GMI, preparando prima la directory:
  md c:\programmi\tomcat\webapps\operazioni\html\com\gmi
  copy c:\apps\gmi\bin\com\gmi\AbstractProxy.class
c:\programmi\tomcat\webapps\operazioni\html\com\gmi
  copy c:\apps\gmi\bin\com\gmi\GmiException.class
c:\programmi\tomcat\webapps\operazioni\html\com\gmi
  copy c:\apps\gmi\bin\com\gmi\GmiRequest.class
c:\programmi\tomcat\webapps\operazioni\html\com\gmi
  copy c:\apps\gmi\bin\com\gmi\GmiResponse.class
c:\programmi\tomcat\webapps\operazioni\html\com\gmi
Finito! Non ci resta che riavviare tomcat ed accedere alla beneamata pagina html all'URL
http://localhost:8080/operazioni/html/Operazioni.html
Compare l'applet... schiaccio il bottone... e uala! Ecco a voi la somma e il prodotto di
due numeri realizzati con un sistema distribuito mediante HTTP.
6. Conclusioni?
---------------
Okay, spero di essermi spiegato decentemente, anzi, mi sembra di si :-D, ma comunque
dovrai essere tu (voi) a dirmi quali parti non sono chiare. 
Insomma, per ogni problema, postate e io (o il NG) cerchero' di risolverli.
Salutoni,
    Bruno.
