tomcat-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Orestes Mas <ores...@tsc.upc.es>
Subject Re: applet-servlet communication
Date Tue, 30 Jan 2001 09:41:10 GMT
I wrote a pair applet-servlet to do a server-based circuit simulation from an
applet located in some client computer. Here are the sources, FYI (yet in
development). If you want, you can email me directly to discuss the
implementation details.

Applet source
follows----------------------------------------------------------------------
This applet has a simple GUI interface to allow the user to input a electronic
circuit description (text format) in a multi-line text edit control. Then, by
pressing the "Simulate" button, the text edit content is sent to the servlet
via a POST method. The servlet writes down this text to a file and invokes the
simulator (ng-spice), sending the results back to the applet for displaying
them into the user screen.

//Title:       SPICE - Applets i Servlets
//Version:
//Copyright:   Copyright (c) 2000
//Author:      Orestes Mas
//Company:     GEC-UPC
//Description: Execució de SPICE en mode client-servidor

package es.upc.gec;

import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import java.net.*;
import java.io.*;

public class SpiceApplet extends Applet {
  boolean isStandalone = false;
  BorderLayout Layout = new BorderLayout();
  Label titol = new Label();
  Panel panellBotons = new Panel();
  Button botoSimular = new Button();
  Button botoVisualitzar = new Button();
  TextArea arxiu = new TextArea();
  private String arxiuCIR = "";
  private String arxiuOUT = "";
  private String direccio = "http://<your servlet URL here...>/SPICEServlet";
  private URL urlservlet;             //Es crea la URL
  private URLConnection conservlet;
  private ObjectOutputStream sortida;   //Streams de comunicació amb el
Servlet
  private ObjectInputStream entrada;

  //Construct the applet
  public SpiceApplet() {
  }

  //Initialize the applet
  public void init() {
    try  {
      jbInit();
    }
    catch(Exception e)  {
      e.printStackTrace();
    }
  }

  //Component initialization
  private void jbInit() throws Exception {
    titol.setFont(new java.awt.Font("SansSerif", 0, 20));
    titol.setText("SPICE - Simulador Remot");
    this.setLayout(Layout);
    botoSimular.setLabel("Simular");
    botoSimular.addActionListener(new java.awt.event.ActionListener() {

      public void actionPerformed(ActionEvent e) {
        botoSimular_actionPerformed(e);
      }
    });
    botoVisualitzar.setEnabled(false);
    botoVisualitzar.setLabel("Veure .OUT");
    botoVisualitzar.addActionListener(new java.awt.event.ActionListener() {

      public void actionPerformed(ActionEvent e) {
        botoVisualitzar_actionPerformed(e);
      }
    });
    arxiuCIR = "Circuit de prova\n";
    arxiuCIR += "* Canvia el titol per un de mes adient\n";
    arxiuCIR += "* i entra la descripcio del circuit a continuacio\n";
    arxiu.setFont(new java.awt.Font("Monospaced", 0, 14));
    arxiu.setText(arxiuCIR);
    this.add(titol, BorderLayout.NORTH);
    this.add(panellBotons, BorderLayout.SOUTH);
    panellBotons.add(botoSimular, null);
    panellBotons.add(botoVisualitzar, null);
    this.add(arxiu, BorderLayout.CENTER);
  }

  //Get Applet information
  public String getAppletInfo() {
    return "Applet Information";
  }

  void botoSimular_actionPerformed(ActionEvent e) {
    // 1) Desactivar el botó de "Veure .OUT" i netejar continguts
    botoVisualitzar.setEnabled(false);
    // 2) Copiar el contingut de la TextArea a una var. interna
    arxiuCIR = arxiu.getText();
    try {
        // 3) Obrir una connexió amb el Servlet
        //    Missatge: Connectant amb el simulador remot...
        titol.setText("Connectant amb el simulador remot...");
        urlservlet = new URL(direccio);
        conservlet = urlservlet.openConnection();   // Obrim connexió amb el
Servlet
        // Fixem diversos paràmetres de la connexió...
        conservlet.setDoInput(true);
        conservlet.setDoOutput(true);
        conservlet.setUseCaches(false);
        conservlet.setDefaultUseCaches(false);

conservlet.setRequestProperty("Content-Type","application/octet-stream");

        // 4) Enviar el contingut de la TextArea
        //    Missatge: Enviant .CIR al simulador...
        titol.setText("Connectat: Enviant .CIR al simulador...");
        //Se crea un Stream de sortida (para objetos).
        sortida = new ObjectOutputStream(conservlet.getOutputStream());
        sortida.writeObject(arxiuCIR);   // Se escribe el objeto.

        // 5) Esperar resposta i col.locar-la en un objecte intermig
        //    Missatge: Esperant resposta...
        titol.setText("Arxiu enviat: Esperant resposta...");
        //Se abre un Stream de entrada, (importante, tanto si se esperan datos
como si no)
        entrada = new ObjectInputStream(conservlet.getInputStream());

        //Se lee el objeto, es necesario un "moldeo" del objeto leido.
        arxiuOUT = (String)entrada.readObject();
        entrada.close();  //Se cierran las conexiones.
        sortida.close();
    } catch (IOException ex) {titol.setText("Excepció!!!");}
      catch (ClassNotFoundException ex) {}

    // 6) Resposta rebuda: Canviar etiqueta
    titol.setText("Resposta rebuda!");
    // 7) Activar el botó de "Veure .OUT"
    botoVisualitzar.setEnabled(true);
  }

  void botoVisualitzar_actionPerformed(ActionEvent e) {
    //   Aprofito per tornar a deixar el títol com estava...
    titol.setText("SPICE - Simulador Remot");
    // Si hem pitjat "Veure .CIR"...
    if (botoVisualitzar.getLabel() == "Veure .CIR") {
        //   1) Activar el botó de simular
        botoSimular.setEnabled(true);
        //   2) Canviar el contingut del botó de visualització
        botoVisualitzar.setLabel("Veure .OUT");
        //   3) Actualitzar els continguts de la TextArea
        arxiu.setText(arxiuCIR);
        arxiu.setEditable(true);
    } else {
    // Si hem pitjat "Veure .OUT"...
        //   1) Desactivar el botó de simular
        botoSimular.setEnabled(false);
        //   2) Canviar el contingut del botó de visualització
        botoVisualitzar.setLabel("Veure .CIR");
        //   3) Canviar el contingut de la TextArea
        arxiu.setText(arxiuOUT);
        arxiu.setEditable(false);
    }
  }

}

Servlet Source
follows-------------------------------------------------------------------
package es.upc.gec;

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.util.*;
import java.lang.*;

public class SPICEServlet extends HttpServlet {
  private String textCIR = "";
  private String textOUT = "";
  private ObjectInputStream appletIn;
  private ObjectOutputStream appletOut;
  private File arxiuCIR;
  private Process spiceProc;

  //Initialize global variables
  public void init(ServletConfig config) throws ServletException {
    super.init(config);
  }

  //Process the HTTP Post request
  public void doPost(HttpServletRequest request, HttpServletResponse response)

         throws ServletException, IOException {
    /* Aquest primer bloc hauria d'anar protegit per un try-catch,
       pero si aquest codi tan elemental falla, la cosa sera massa greu com
       per poder fer-hi res, i prefereixo passar l'excepcio cap amunt
    */
    // Obrim el canal d'entrada associat a l'objecte request
    // i l'associem a un canal que retorni objectes
    appletIn = new ObjectInputStream(request.getInputStream());
    // Fem el mateix amb el canal de sortida
    appletOut = new ObjectOutputStream(response.getOutputStream());

    //Llegim l'objecte i l'ammotllem a String
    try {
        textCIR = (String)appletIn.readObject();
    } catch (ClassNotFoundException e) {
        textOUT = "Error en la comunicacio amb el servidor";
    }

    // Faig un bloc try-catch per poder sortir amb elegancia dels subblocs
    // i amb l'excepcio re-raised per executar la clausula finally
    try {
        // Ara creem els arxius temporals .CIR i .OUT
        try{
            File tempDir = new File("/tmp");
            arxiuCIR = File.createTempFile("temp",".cir",tempDir);
        } catch (IOException e) {
            textOUT = "Error creant l'arxiu temporal";
            throw e;
        }

        // Si tot OK, escrivim l'arxiu .CIR
        try{
            BufferedWriter bw = new BufferedWriter(new FileWriter(arxiuCIR));
            bw.write(textCIR);
            bw.close();
        } catch (IOException e) {
            textOUT = "Error escrivint arxiu .CIR";
            throw e;
        }

        // Si tot ok, executem el ng-spice amb els paràmetres adients
        // El nom de l'arxiu .CIR l'obtenim de fer arxiuCIR.toString()
        // Similarment per obtenir el nom de l'arxiu .OUT
        try {
            String ordre = "/usr/local/ngspice/bin/ngspice -n -b ";
            ordre += arxiuCIR.toString();
            spiceProc = Runtime.getRuntime().exec(ordre);
            if (spiceProc.waitFor() != 0) {
                throw new IOException();
            }
        } catch (IOException e) {
            textOUT = "Error en executar SPICE al servidor";
            throw e;
        } catch (InterruptedException e) {
            textOUT = "Error: Execucio interrompuda per usuari extern";
            throw e;
        }

        // Si tot OK, llegim l'arxiu
        try{
            BufferedReader br = new BufferedReader(
                                new
InputStreamReader(spiceProc.getInputStream()));
            textOUT = "";
            String linia = br.readLine();
            while (linia != null) {
                textOUT = textOUT + linia + "\n";
                linia = br.readLine();
            }
            br.close();
        } catch (IOException e) {
            textOUT = "Error llegint arxiu .OUT";
        }
    } catch (Exception e) {
    } finally {
        //Escrivim el texte del .OUT al canal de l'Applet
        appletOut.writeObject(textOUT);
        // Tanquem els canals de comunicacio amb l'Applet
        appletIn.close();
        appletOut.close();
        if (arxiuCIR.exists()) arxiuCIR.delete();
    }
    response.setContentType("text/html");
  }

  //Get Servlet information
  public String getServletInfo() {
    return "Servlet que fa de front-end local del simulador SPICE";
  }
}
------------------------------------------------------------------------------------------

(Note: If you have any suggestion for improving this code, please share them
with me ;-)
(Note 2: Some comments are in Catalan (my language), others in spanish. If you
have troubles with them, ask me.)

Carlos R Armas wrote:

> I am trying to have an applet communicate with a servlet. I don't want
> to use <form> so I can't set the method to GET/POST. I do want to restrict
> the servelt to only use POST, not GET.
>
> The HttpServletResponse/HttpServletRequest classes are being used to
> exchange the messages. I have the applet "sending" the data... I believe
> using the POST method. The servlet on the other hand, gets the initial
> communication and session information.... but the actual data never
> arrives and the method that the servlet claims to have used is GET. The
> servlet communicates back to the applet with no problem.
>
> Now, the question is: Is there some configuration needed so that when the
> applet sends the information (to tomcat?) it can be passed on to the
> servlet using the chosen -POST- delivery method?
>
> The servlet works fine if I test it with a html file that has a form which
> uses POST to send the data. So half the implementation is working.
>
> Any help will be appreciated.
>
> armas
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tomcat-user-unsubscribe@jakarta.apache.org
> For additional commands, email: tomcat-user-help@jakarta.apache.org

Mime
View raw message