Categorías del Tutorial

icono_twiter icono LinkedIn icono Facebook Icono Xing
Roberto Canales Mora

Creador y propietario de AdictosAlTrabajo.com, Director General de Autentia S.L., Ingeniero Técnico de Telecomunicaciones y Executive MBA por el Instituto de Empresa 2007.
Twitter:

Autor de los Libros: Planifica tu éxito: de aprendiz a empresario y Informática profesional, las reglas no escritas para triunfar en la empresa

Puedes consultar mi CV y alguna de mis primeras aplicaciones (de los 90) aquí

Ver todos los tutoriales del autor

Fecha de publicación del tutorial: 2003-11-06

Tutorial visitado 52.273 veces Descargar en PDF
Comunicación entre Applets y Servlets

Comunicación entre Applets y Servlets

Nos ha realizado muchas consultas sobre la comunicación entre applets y servlets.

Un applet y un servlet se pueden comunicar de muchos modos (sockets, RMI, corba, etc) aunque el modo más sencillo de hacerlo es a través de peticiones HTTP.

Preparación

Primero, vamos a crear un applet básico. Este applet lo hemos creado a través de NetBeans por lo que podéis encontrar algunas partes del código o comentarios en inglés.

/*
 * appletsimple.java
 *
 * Created on November 5, 2003, 10:51 PM
 */

package roberto;

/**
 *
 * @author Roberto Canales
 */
public class appletsimple extends java.applet.Applet {
    
    /** Initializes the applet appletsimple */
    public void init() {
        initComponents();
    }
    
    /** This method is called from within the init() method to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    private void initComponents() {
        label1 = new java.awt.Label();
        mensajeenviar = new java.awt.TextArea();
        label2 = new java.awt.Label();
        mensajerecibir = new java.awt.TextArea();
        botonenviar = new java.awt.Button();

        setLayout(new java.awt.GridLayout(5, 1, 2, 5));

        label1.setAlignment(java.awt.Label.CENTER);
        label1.setForeground(new java.awt.Color(51, 51, 255));
        label1.setText("Introduzca el mensaje a enviar al servidor");
        add(label1);

        add(mensajeenviar);

        label2.setAlignment(java.awt.Label.CENTER);
        label2.setForeground(new java.awt.Color(255, 0, 0));
        label2.setText("Mensaje recibido del servidor");
        add(label2);

        add(mensajerecibir);

        botonenviar.setLabel("Pulsar para conectar al servidor");
        botonenviar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                botonenviarActionPerformed(evt);
            }
        });

        add(botonenviar);

    }

    private void botonenviarActionPerformed(java.awt.event.ActionEvent evt) {
        
     String s_textoaenviar = mensajeenviar.getText();
        mensajerecibir.setText("Simulacion: " + s_textoaenviar);
 
       this.showStatus("Botón Pulsado");

    }
    
    
    // Variables declaration - do not modify
    private java.awt.Button botonenviar;
    private java.awt.Label label1;
    private java.awt.Label label2;
    private java.awt.TextArea mensajeenviar;
    private java.awt.TextArea mensajerecibir;
    // End of variables declaration
    
}     

Como podéis observar, en depuración, el código anterior lo único que hace es mostrar un pequeña ventana  donde al introducir un texto en la parte superior y pulsar el botón, muestra un texto en la parte de inferior y un mensaje en la barra de estado.

Para poder probar nuestro programa de un modo efectivo, debemos crear una página HTML y colgarla de un servidor Web.

<html>
<body> 
<p align="left">
<applet width="400" height="300" code="roberto.appletsimple.class" codebase="./">Applet que se comunica con servlet</applet>
</p>

</body>
</html>

El aspecto de nuestra página en el navegador es:

Ahora, vamos a crear el servlet que se ejecutará en el servidor. Este servlet solamente se encarga de recoger los parámetro que recibe en la petición Get o Post y genera una página de respuesta mostrándolos.

/*
* servletsimple.java
*
* Created on November 5, 2003, 11:38 PM
*/

import java.io.*;
import java.net.*;
import java.util.*;

import javax.servlet.*;
import javax.servlet.http.*;

/**
*
* @author Roberto Canales
* @version
*/
public class servletsimple extends HttpServlet {

protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();

out.println("<html>");
out.println("<head>");
out.println("<title>Servlet</title>");
out.println("</head>");
out.println("<body>");


Enumeration e = request.getParameterNames();

while(e.hasMoreElements())
{
String s_clave = e.nextElement().toString();
String s_aux = request.getParameter(s_clave);
out.println("<br>El parámetro: <B>" + s_clave + "</B> vale: <B>" + s_aux + "</B>");
}


out.println("</body>");
out.println("</html>");

out.close();

}

protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}

protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
}

Podemos ver la petición y la respuesta en la siguiente pantalla.

 

Insertar código comunicaciones

Ahora lo único que nos queda en modificar el código del applet para hacer la petición HTTP al servidor. Esta versión del código os muestra como hacerlo a través de POST pero podéis ver que también está dentro del código la gunción para hacerlo a través del comando GET.

peticionPost(s_textoaenviar)

Vamos a comentar las funciones más significativas (por ejemplo con la fucnión GET):

Primero, recuperamos el Host del que descargamos el Applet

           String host = this.getCodeBase().getHost();

Posteriormente, debemos codificar los caracteres especiales al juego compatible con HTTP ()

            String peticion = "/servlet/servletsimple?param1=" + URLEncoder.encode(mensaje);

Generamos la URL que representa el recurso a recuperar (en este caso el servlet)             

miurl = new URL(getCodeBase(),peticion);

 Ahora conectamos con el recurso

           InputStream buffer = miurl.openStream();
 

/*
 * appletsimple.java
 *
 * Created on November 5, 2003, 10:51 PM
 */

package roberto;

import java.net.*;
import java.io.*;

/**
 *
 * @author  Roberto Canales
 */
public class appletsimple extends java.applet.Applet {
    
    /** Initializes the applet appletsimple */
    public void init() {
        initComponents();
    }
    
    /** This method is called from within the init() method to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    private void initComponents() {
        label1 = new java.awt.Label();
        mensajeenviar = new java.awt.TextArea();
        label2 = new java.awt.Label();
        mensajerecibir = new java.awt.TextArea();
        botonenviar = new java.awt.Button();

        setLayout(new java.awt.GridLayout(5, 1, 2, 5));

        label1.setAlignment(java.awt.Label.CENTER);
        label1.setForeground(new java.awt.Color(51, 51, 255));
        label1.setText("Introduzca el mensaje a enviar al servidor");
        add(label1);

        add(mensajeenviar);

        label2.setAlignment(java.awt.Label.CENTER);
        label2.setForeground(new java.awt.Color(255, 0, 0));
        label2.setText("Mensaje recibido del servidor");
        add(label2);

        add(mensajerecibir);

        botonenviar.setLabel("Pulsar para conectar al servidor");
        botonenviar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                botonenviarActionPerformed(evt);
            }
        });

        add(botonenviar);

    }
    
    private void botonenviarActionPerformed(java.awt.event.ActionEvent evt) {
        
        String s_textoaenviar = mensajeenviar.getText();
        mensajerecibir.setText("Simulacion: " +  peticionPost(s_textoaenviar));
        
    }
    
    // enviamos la peticion por post
    String peticionPost(String mensaje) {
        URL miurl = null;
        String cadenaaux = null;
        String cadenaretorno = "";
        
        String consulta = "param1=" + URLEncoder.encode(mensaje);
        
        try {
            String host = this.getCodeBase().getHost();
            String peticion = "/servlet/servletsimple";
            miurl = new URL(getCodeBase(),peticion);
            
            URLConnection conexion = miurl.openConnection();
            conexion.setDoOutput(true);
            OutputStreamWriter buffersalida = new OutputStreamWriter(conexion.getOutputStream());
            buffersalida.write(consulta);
            buffersalida.flush();
            
            BufferedReader bufferentrada = new BufferedReader(new InputStreamReader(conexion.getInputStream()));
            String linea = null;
            
            while ((linea = bufferentrada.readLine()) != null) {
                cadenaretorno += linea;
            }
            
            buffersalida.close();
            bufferentrada.close();
        }
        catch (Exception e) 
        {
            return "Error al generar url " + e.getMessage();
        }
        
        return cadenaretorno;

        
    }
    
    // enviamos por get la petición
    String peticionGet(String mensaje) {
        URL miurl = null;
        String cadenaaux = null;
        String cadenaretorno = "";
        
        try {
            String host = this.getCodeBase().getHost();
            String peticion = "/servlet/servletsimple?param1=" + URLEncoder.encode(mensaje);
            miurl = new URL(getCodeBase(),peticion);
            InputStream buffer = miurl.openStream();
            BufferedReader bufferreader = new BufferedReader(new InputStreamReader(buffer));
            
            while( (cadenaaux = bufferreader.readLine()) != null) {
                cadenaretorno += cadenaaux;
            }
            
            buffer.close();
        }
        catch (Exception e) {
            return "Error al generar url " + e.getMessage();
        }
        
        return cadenaretorno;

    }
    
    
    // Variables declaration - do not modify
    private java.awt.Button botonenviar;
    private java.awt.Label label1;
    private java.awt.Label label2;
    private java.awt.TextArea mensajeenviar;
    private java.awt.TextArea mensajerecibir;
    // End of variables declaration
    
}     

Y el resultado es 

Sencillo verdad .....

Serialización de comunicaciones 

Una vez que sabemos hacer esto, podemos utilizar una petición POST  de un modo un poquito especial .....

serializando la llamada entre el cliente y el servidor y de este modo, enviar y recibir objetos completos.

Hacemos un pequeño cambio, primero en el Applet, donde vamos a enviar un array

// enviamos la peticion por post
String peticionPost(String mensaje) {
   URL miurl = null;
   String cadenaaux = null;
   String cadenaretorno = "";

   String consulta = "param1=" + URLEncoder.encode(mensaje);

   try {
   String host = this.getCodeBase().getHost();
   String peticion = "/servlet/servletsimple";
   miurl = new URL(getCodeBase(),peticion);

   URLConnection conexion = miurl.openConnection();
   conexion.setDoOutput(true);
   ObjectOutputStream buffersalida = new ObjectOutputStream(conexion.getOutputStream());
   //buffersalida.write(consulta);

   int array[] = new int[10];
   for(int i=0;i<array.length;i++)
   {
       array[i] = i*3;
   }

   buffersalida.writeObject(array);


   buffersalida.flush();

   BufferedReader bufferentrada = new BufferedReader(new  InputStreamReader(conexion.getInputStream()));
   String linea = null;

   while ((linea = bufferentrada.readLine()) != null) {
      cadenaretorno += linea;
      }

   buffersalida.close();
   bufferentrada.close();
   }
   catch (Exception e) 
   {
      return "Error al generar url " + e.getMessage();
   }

   return cadenaretorno;

}

Y ahora cambiamos el servlet

protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
   response.setContentType("text/html");
   PrintWriter out = response.getWriter();

   out.println("<html>");
   out.println("<head>");
   out.println("<title>Servlet</title>");
   out.println("</head>");
   out.println("<body>");

/*
Enumeration e = request.getParameterNames();

while(e.hasMoreElements())
{
String s_clave = e.nextElement().toString();
String s_aux = request.getParameter(s_clave);
out.println("<br>El parámetro: <B>" + s_clave + "</B> vale: <B>" + s_aux + "</B>");
}
*/

   try
   {
      ObjectInputStream bufferentrada = new ObjectInputStream(request.getInputStream());

      int[] arrayRecuperado = (int[])bufferentrada.readObject();

      for(int i=0;i<arrayRecuperado.length;i++)
      {
          out.println("El valor recuperado del elemento " + i + " es " + arrayRecuperado[i]);
      }
   }
   catch(Exception e)
   {
      out.println("Error al recuperar datos");
   }


   out.println("</body>");
   out.println("</html>");

   out.close();
}

Y en el sentido contrario..... es exactamente lo mismo ........

Esto es impresionante..... imaginaos lo rápido que es el desarrollo. Además, cuando nos cuentan sobre nuevas tecnologías de interacción Web, como Web Services ...... tampoco nos asusta tanto

 

Proxys y autentificación

Por cierto, si tenéis proxy ..... hay que establecer unas propiedades

System.setProperty("proxyHost", "host");

System.setProperty("proxyPort", "puerto");

Y si tenéis seguridad (autentificación simple) en el servidor, debéis añadir unas líneas a vuestro objeto URLConnection :

conexion.setRequestProperty( "Authorization","BASIC " + passwordencriptadaenbase64);
conexion.setRequestProperty("content-type", "text/html");

 

De todos modos, debéis tener en cuenta donde usar los applets ....  Yo os recomendaría restringirlos a Intranets.

Sobre el Autor ..

A continuación puedes evaluarlo:

Regístrate para evaluarlo

Por favor, vota +1 o compártelo si te pareció interesante

Share |
Anímate y coméntanos lo que pienses sobre este TUTORIAL:

Fecha publicación: 2009-05-04-07:41:59

Autor:

[Jordan Torres] Muy bueno el tutorial, acaba de funcionarme todo perfectamente pero sin la serialización, pero tengo muy buena fé que todo funcionara a la perfección, pues les comento que yo caí en la necesidad de utilizar applets por un tema de autentificación para un sistema que necesita seguridad web y como voy a necesitar datos de la pc cliente que invocará el sistema me comentaron que el applet se ejecuta desde el cliente asi es que, que mejor no? aunque fue lo primero que se me ocurrio, gracias a todos los involucrados.

Fecha publicación: 2009-04-28-07:22:09

Autor:

[Omar Danilo Berroter] Muy bueno, como casi todos los tutoriales de su sitio. Desde hace mucho visito su sutio en busca de orientacion, se les agradece mucho. Omar D' Berroteran(LKF) Arquitecto de Softare Java Developer Amante de Java ---------------------------------------- - Todo es posible. - Si no se puede, es porque no se como hacerlo. - La computadora y JAVA solo estan limitado por la imaginacion de el usuario. ----------------------------------------

Fecha publicación: 2009-04-09-05:15:31

Autor:

[golok] gracias por el tutorial ... estoy recien empezando con este tema y esta publicacion me ayudara bastante PERO (la pregunta puede ser algo basica pero quiero asegurarme bien antes de empezar). ¿que pasa con los puertos de comunicación entre cliente y host? verán, tengo una pequeña java nativa conectada a la internet por medio de un router En el, implemento un pequeño server http. Este server toma request por el puerto 80 y genera los puertos de comunicaciones al azar (un firewall no me preocupa aun). Por el lado del cliente se levanta un applet en el cual genero pequeños mensajes (valores de variables) Los quiero enviar a traves de http tuneling al server para otros usos que no vale la pena mencionar En concreto la pregunta es : ¿como sabe el applet por que puertos debe enviar y recibir la informacion?¿es que el browser secretamente se encarga de poner estos stream de datos en los puertos precisos? Aclarando esto puedo quedarme tranquilo ya que mi aplicacion es bastante sencilla. de antemano gracias.

Fecha publicación: 2009-04-07-06:02:50

Autor:

[golok] gracias por el tutorial ... estoy recien empezando con este tema y esta publicacion me ayudara bastante PERO (la pregunta puede ser algo basica pero quiero asegurarme bien antes de empezar). ¿que pasa con los puertos de comunicación entre cliente y host? verán, tengo una pequeña java nativa conectada a la internet por medio de un router En el, implemento un pequeño server http. Este server toma request por el puerto 80 y genera los puertos de comunicaciones al azar (un firewall no me preocupa aun). Por el lado del cliente se levanta un applet en el cual genero pequeños mensajes (valores de variables) Los quiero enviar a traves de http tuneling al server para otros usos que no vale la pena mencionar En concreto la pregunta es : ¿como sabe el applet por que puertos debe enviar y recibir la informacion?¿es que el browser secretamente se encarga de poner estos stream de datos en los puertos precisos? Aclarando esto puedo quedarme tranquilo ya que mi aplicacion es bastante sencilla. de antemano gracias.

Fecha publicación: 2006-10-17-11:25:00

Autor:

[roque] es muy bueno me ayudo bastante!!! sigan con estos tutoriales

Fecha publicación: 2006-09-26-09:40:55

Autor:

[Nelson López] Hola.. bueno, agradezco la buena intención al dejar este pequeño tutorial sobre como comunicar un Arlet con un servlet, pero lamentablemente me paso lo típico… un error al final de todo… Es en la línea: String peticion = "/servlet/servletsimple?param1=" + URLEncoder.encode(mensaje); El asunto es que utilizo Jbuilder 2005, enterprice edition y el compilador me tira un warning en esta línea, pues dice que encode debería tener dos estring en vez de uno, me dice [Deprecation] encode(java.lang.string) in java.lang.net.URLEncoder has been deprecated Bueno, la verdad es que no tengo idea del por que del error, pero se soluciona agregando otro string, lamentablemente no se cual agregar. Un problema bastante obvio pues como estoy comenzando en JAVA no tengo muchos recursos a los cuales echar mano y solucionar el problema. Por lo que si alguien tiene una idea de cómo solucionar el problema y además tiene la buena voluntad de tomarse un tiempo y escribirme al mail, le estaría muy agradecido. Me despido desde chile.

Fecha publicación: 2006-08-11-08:52:00

Autor:

[Jose Anibal] La Verdad que Muy Bueno, salvo que estoy intentando desde hace una semana llamar al servlet del fileupload desde una aplicacion JAVA y no puedo hacer coincidir los parametros paar que lo entienda de la misma manera del demo a travez de HTML. Conclusion, me gustaria saber cual es mínimamente un ejemplo igual que en HTML pero en JAVA 2.

Fecha publicación: 2006-06-07-08:05:08

Autor:

[Carlos] Excelente página, jamás la quiten!! He podido encontrar santo y seña de lo que necesitaba para mi trabajo. Gracias.