Tecnología WEB Programación en el lado del cliente Antonio da Silva Fariña [email protected] 3 3.1 Programación en el lado del cliente Introducción Uno de los principales problemas de la ejecución de aplicaciones distribuidas a través de Internet se refiere a la velocidad de transmisión, y más en concreto, a la cantidad de información que circula por la Red. Esa velocidad se traduce en lentitud de respuesta a los comandos introducidos por el cliente en los múltiples interfaces de datos que se presentan en los documentos HTML, como son los formularios, enlaces, imágenes etc. Para reducir los dos problemas que se plantean (saturación y lentitud), se plantean soluciones en el entorno del cliente Web, capaces de manejar los objetos contenidos en las páginas HTML, así como atender a las acciones realizadas por el cliente, sin necesidad alguna de transmisión hacia el servidor (que, en estos casos, sería incapaz de ofrecer respuesta a los comandos tratados a nivel local). La rápida respuesta ofrecida por el programa local permite dar una sensación más realista dentro del navegador, dejando al protocolo únicamente los aspectos relacionados con el envío de información. Se permite así mejorar el aspecto de presentación de la aplicación, además de gestionar de forma rápida y sencilla algunos aspectos hasta ahora centralizados en el servidor (con el aumento de demoras que ello provoca). Tecnología Web Figura 3-1 : Programación en el navegador Las tecnologías típicas que permiten la codificación de pequeñas aplicaciones a ejecutar en el entorno local del navegador son: 3.2 Lenguajes de Script Applets Java Lenguajes de Script Los lenguajes de script están diseñados para la manipulación de los eventos y objetos contenidos en una página Web, de forma local y sin necesidad de transmisión alguna por la Red. Son programas incluidos en la página HTML y que son interpretados por el navegador, mejorando la interacción con el usuario. Permiten realizar algunas tareas simples en la parte del cliente: Algunos cálculos simples Validación de los datos de los formularios Mensajes de alerta Por lenguaje Script entendemos lenguajes orientados al documento; nunca será posible realizar un programa completo en él, sino que el ámbito de actuación quedará restringido al documento en el que se ejecuta, y donde va inmerso el código script. Ante las acciones realizadas por el usuario, el programa captura el evento relacionado con la acción, y ejecuta el código de atención. Mediante esta técnica, es posible la ejecución de código en muchas acciones comunes en un entorno Web, como pueden ser: 3-2 Programación en el lado del cliente apertura de nuevos documentos Pulsación de botones Introducción y envío de datos en formularios ... y que son controlados mediante la interceptación de los métodos asociados a cada objeto (pulsación, enfoque, paso por encima, ...). La manipulación de los objetos de la página se realiza de forma directa, es decir, en su definición (en HTML) cada objeto lleva asociado un nombre, que será el que se utilice para acceder a sus propiedades (definidas en la jerarquía de objetos propia de cada lenguaje). De forma resumida, se puede decir que se trata de lenguajes de programación sencillos, con restricciones de acceso a los recursos locales de la máquina (disco duro, memoria), y en los que es posible realizar pequeñas aplicaciones cliente/servidor; aunque el principal ámbito de aplicación es local. 3.2.1 Lenguajes orientados a objetos Los lenguajes de Script usados en entorno WEB están diseñados para la manipulación de los objetos contenidos en un documento HTML (visualizado a través del navegador). Dichos objetos se definen dentro de una jerarquía de objetos, propia de cada navegador (cada uno define la suya propia, aunque muy parecida entre ellos). Esto causa algunos problemas, por ejemplo el mismo código será valido un navegador y producirá errores de ejecución en otro. Una acción inicial muy típica es detectar el tipo de navegador usado y actuar en consecuencia. 3.2.2 Inserción en HTML Se utilizará la etiqueta <script> de la forma siguiente: <SCRIPT LANGUAJE="VBScript"> <!-<instrucciones> --> </SCRIPT> donde se puede ver como se utilizan los comentarios de HTML (<!-- y -->), para aquellos navegadores que no sean capaces de interpretarlo. Los lenguajes más comunes son: JavaScript: Desarrollado por Netscape para su navegador Mozilla. Microsoft Internet Explorer soporta una versión propia muy parecida denominada JScript. VBScript: Desarrollado por Microsoft y soportado por Internet Explorer. 3-3 Tecnología Web 3.2.3 JavaScript En las líneas siguientes se hará un pequeño repaso de la sintaxis de JavaScript. En primer lugar hay que destacar que este lenguaje no tiene nada que ver con Java, aparte del nombre y la sintaxis. El ámbito de utilización, la ejecución y los objetivos de ambos lenguajes son totalmente distintos. Al igual que sucede en C/C++ las sentencias terminan con un punto y coma y se forman sentencias compuestas mediante llaves; Los operadores son similares, por no decir los mismos, a los ya conocidos en C/C++: + (que sirve también para concatenar cadenas), -, *, /, %, ++, --, =, ==, !=,<,>,<=>,>=, &&, ||, etc. Los comentarios se escriben usando la doble barra ( // ) que indica que el resto de la línea no se interpreta. 3.2.3.1 Variables En JavaScript se usa la palabra reservada var para declarar variables. A diferencia de un lenguaje compilado, no es necesario indicar el tipo de la variable. Esto se deduce del contexto, al usar la variable el interprete ya sabrá de que tipo es. Ejemplo: var variable; variable = 37; variable = “hola”; //la uso como si fuera de tipo entero //la uso como una cadena de caracteres Los arrays se construyen en tiempo de ejecución, no siendo necesario especificar su tamaño. var arrayDeCadenas = new Array(); arrayDeCadenas[1] = "Primera cadena"; arrayDeCadenas[2] = "Segunda cadena"; //Los elementos del array pueden ser de cualquier tipo 3.2.3.2 Estructuras de control En JavaScript disponemos de las estructuras de control típicas de C/C++ y además con la misma sintaxis. Como se suponen ya conocidas por el lector se hará un breve repaso de las mismas. Estructura if...else if (numero==0) { numero+=10; } else { numero--; } 3-4 Programación en el lado del cliente Estructura for for(contador=1; contador<=10; contador++ ){ // Sentencias del bucle } Estructura for ..in Esta estructura no existe en C y sirve para recorrer todos los elementos de un array. var tabla = new Array(); for ( contador in tabla ) { // Sentencias del bucle } Estructuras while y do..while var numero=0; while (numero==1) { // Sentencias del bucle } do { // Sentencias del bucle } while( numero == 0 ); 3.2.3.3 Control de eventos Un evento es una indicación de que algo ha sucedido en el entorno del programa. Típicamente los eventos los provoca la pulsación de una tecla, el movimiento del ratón, la carga de una página, etc. Al programador se le ofrece un mecanismo para capturar esos eventos y ejecutar una función cuando estos se produzcan. Este mecanismo evita estar esperando de forma activa a que algo suceda. Los controladores de evento se asocian al elemento HTML que se desee, indicando cual es el evento a capturar. Ejemplo: <head> <script languaje="JavaScript"> function bienvenida() { // sentencias de la funcion } </script> </head> <!— Cada vez que se cargue la página se ejecuta la función bienvenida. --> <body onLoad="bienvenida()"> La lista de eventos disponible es bastante amplia, en la tabla siguiente se muestran algunos de ellos. 3-5 Tecnología Web Evento Acción OnLoad Terminar de cargarse una página OnUnLoad Salir de una página (descargarla) OnMouseOver Pasar el ratón por encima OnMouseOut Que el ratón deje de estar encima OnSubmit Enviar un formulario OnClick Pulsar un elemento OnBlur Perder el cursor OnChange Cambiar contenido o perder el cursor OnFocus Conseguir el cursor OnSelect Seleccionar texto 3.2.3.4 Objetos predefinidos En el lenguaje existen una serie de objetos predefinidos que representan distintos elementos, tanto del navegador como de la página que se está presentando actualmente. Cada uno de estos objetos puede tener propiedades que pueden ser a su vez otros objetos. Por ejemplo el objeto window que representa una ventana tiene una propiedad llamada document que representa el documento HTML que se está presentando y este a su vez contiene un objeto form que contiene todos los formularios de esa página. A continuación se hará una pequeña descripción de los objetos más típicos y se remite al lector a la guía de referencia para una completa descripción de todos los objetos disponibles y sus propiedades y métodos. 3-6 Window: Representa la ventana sobre la que estamos actuando. open : Permite abrir una nueva ventana close : Cierra la ventana alert : Abre una ventana con un mensaje Document: Representa el documento html write : Escribe en la página form : array con los formularios de la página History: Páginas visitadas anteriormente. back : Retrocede en la lista de páginas visitadas forward : Avanza en la lista de páginas visitadas Otros objetos: Date Navigator: Tipo de navegador Screen : Fecha actual : Propiedades de la pantalla Programación en el lado del cliente 3.2.3.5 Ejemplos completos El ejemplo siguiente muestra un script que crea una tabla con los nombres de los días de la semana, crea un objeto que representa la fecha actual e imprime en la página HTML la fecha actual. <HTML> <BODY> <!- Comienzo del cuerpo de la página --> <P>Hoy es: <SCRIPT> // array con los nombres de los dias var nombreDias = new Array(); nombreDias[0] = "Domingo"; nombreDias[1] = "Lunes"; nombreDias[2] = "Martes"; nombreDias[3] = "Miercoles"; nombreDias[4] = "Jueves"; nombreDias[5] = "Viernes"; nombreDias[6] = "Sabado"; // Creamos el objeto fecha var fecha = new Date(); // Escritura en el documento actual // El método getDay retorna el día de la semana // y el método getDate retorna el día del mes document.write( nombreDias[ fecha.getDay() ] ); document.write( " y " + fecha.getDate()); </SCRIPT> </P> </BODY> </HTML> Y la apariencia del código en el navegador es la siguiente: Figura 3-2 : Fecha actual Hay que dejar claro que el texto que se muestra dependerá del día que se ejecute el script y el ejemplo que se muestra es solamente ilustrativo de la apariencia que tendría la página. 3-7 Tecnología Web El siguiente ejemplo muestra la creación de distintas ventanas de alerta, confirmación y petición de datos en funciones que se ejecutan como respuesta a un evento, en este caso la pulsación de un botón. <html><head> <script LANGUAGE="JavaScript"> function aviso() { alert("He dicho que no me pinches"); } function confirmacion() { var resp = confirm("Estas seguro ?"); if ( resp == true ) alert("Has respondido ACEPTAR"); else alert("Has respondido CANCELAR"); } function pregunta() { var resp = prompt("Dime algo", "Valor por defecto"); alert("Has respondido " + resp ); } </script> <title>Mensaje de alerta</title> </head><body> <form> <input TYPE="button" NAME="Boton" VALUE="No me pinches" onClick="aviso()"> <input TYPE="button" NAME="Boton" VALUE="Confirmacion" onClick="confirmacion()"> <input TYPE="button" NAME="Boton" VALUE="Pregunta" onClick="pregunta()"> </form></body></html> Y la apariencia del código en el navegador es la siguiente: Figura 3-3 : Mensajes de alerta, confirmación, ... 3-8 Programación en el lado del cliente Al pulsar el primer botón se abrirá una ventana de alerta: Al pulsar el botón de confirmación se abrirá la siguiente ventana: El resultado de la pulsación se puede recoger en una variable tal y como se muestra en el ejemplo. Con el último botón se abre una ventana donde el usuario puede realizar una entrada de datos. En la llamada se especifica el texto a presentar en la ventana y el valor por defecto que debe presentar la entrada. En este otro ejemplo, se ejecuta una función en respuesta a la pulsación de un botón que crea una nueva ventana y escribe en ella una pequeña página HTML. <HTML><HEAD> <SCRIPT LANGUAGE="JavaScript"> // rutina de atención al evento function NuevaVentana() { MiVentana=open("","MiPropiaVentana", "toolbar=no,menubar=no,resizable=yes,status=yes"); MiVentana.document.write("<HEAD><TITLE>Una nueva ventana</TITLE></HEAD>"); MiVentana.document.write("<CENTER><H1><B>Aquí puedes poner lo que quieras</B></H1></CENTER>"); } </SCRIPT> </HEAD><BODY><FORM> <INPUT TYPE="button” NAME="Boton" VALUE="Pincha” onClick=”NuevaVentana()"> </FORM> </BODY> </HTML> 3-9 Tecnología Web Y la apariencia del código en el navegador es la siguiente: Figura 3-4 : Apertura de una nueva ventana Otros ejemplos: <!— Cambia la línea de estado por defecto en la carga.--> <BODY onLoad="defaultStatus=’Bienvenido'; return true"> <!— Cambia la línea de estado al pasar el ratón encima. --> <A HREF=”miPagina.html" onMouseOver="window.status='Visita mi página';return true"> <!— Enlace a la página visitada anteriormente. --> <A HREF=javascript:window.history.back()”> Atrás</A> 3.2.3.6 Validación de formularios Una de las tareas típicas que se realizan en JavaScript es la validación de formularios antes del envío de la información a la aplicación que ha procesarla. Si el usuario no ha rellenado todos los campos, o al menos aquellos que se consideren imprescindibles, para que se va a enviar esa información incompleta al servidor que lo único que provocará es el envío de un mensaje de error por parte de este, con el consiguiente incremento del tráfico en la red. ( sin olvidar la carga computacional que supone para el servidor el recibir mensajes con información insuficiente, procesarlos para darse cuenta de esta circunstancia y responder con una página de error ) 3-10 Programación en el lado del cliente El array document.forms contiene todos los formularios de un documento HTML También se puede acceder a través del nombre que se le haya dado en la declaración. <FORM NAME=“miFormulario”> Cada formulario tiene un array elements con los campos del formulario. También puede accederse a estos campos a través del nombre que se le haya dado en la página HTML. De cada campo podemos saber su tipo ( type ) y su valor ( value ). Además de los checkbox y radio buttons podemos saber si están marcados ( checked ) y de las listas de selección si están seleccionadas ( selected ). Ejemplos: // se accede al primer campo del primer formulario de la // página para saber si es un boton y si está seleccionado if ( ( document.forms[0].elements[0].type == “radio” ) && ( document.forms[0].elements[0].checked ) ) // se accede al campo asignaturas del formulario notas de la // página para saber si la primera opcion está seleccionada if ( document.notas.asignatura.options[0].selected ) 3.2.3.7 Ejemplos de validación de formularios A continuación se muestra un pequeño formulario que solicita al usuario su DNI. Si el usuario pulsa el botón de envío sin rellenar el campo correspondiente se le informa y no se envía el formulario. <HTML> <HEAD> <TITLE>Ejemplo de formularios</TITLE> <SCRIPT LANGUAGE="JavaScript"> function validar() { if (document.notas.dni.value.length != 0) return true; else { alert('Debes darme tu dni'); return false; } } </SCRIPT> </HEAD> <BODY> <FORM NAME="notas" METHOD="POST" ACTION="cgi_bin/notas.exe" onSubmit="return validar()"> DNI: <INPUT NAME="dni" TYPE="text"> <HR><INPUT TYPE="submit" VALUE="consulta"> </FORM> </BODY> </HTML> 3-11 Tecnología Web Siendo la siguiente la apariencia de la página en un navegador: Figura 3-4 : Validación formularios En el siguiente ejemplo se muestra un pequeño examen tipo test construido en forma de formulario. Cuando el usuario desee saber el resultado pulsará al botón y se le informará del número de respuestas correctas. <html> <head> <title>Página nueva 1</title> <script languaje="JavaScript"> function averiguarNota(examen) { var resultado=0; // Se recorren todos los elementos del formulario // comprobando si estan seleccionados y son correctos for (i=0;i<examen.elements.length;i++) if ((examen.elements[i].type=="radio") && (examen.elements[i].value=="bien") && (examen.elements[i].checked)) resultado++; alert("Has acertado "+resultado+" preguntas."); return false; } </script> </head> <body> 3-12 Programación en el lado del cliente <form NAME="examen" onSubmit="return averiguarNota(this);"> <p>Los lenguajes de Script: <br> <input TYPE="radio" NAME="Respuesta1" VALUE="mal"> son compilados<br> <input TYPE="radio" NAME="Respuesta1" VALUE="mal"> se ejecutan siempre en el servidor<br> <input TYPE="radio" NAME="Respuesta1" VALUE="bien"> van incrustados en las páginas HTML<br> <br> El atributo <tt>window.status</tt> contiene: <br> <input TYPE="radio" NAME="Respuesta2" VALUE="bien"> el valor de la barra de estado<br> <input TYPE="radio" NAME="Respuesta2" VALUE="mal"> el valor por defecto de la barra de estado<br> <input TYPE="radio" NAME="Respuesta2" VALUE="mal"> ciertas características de la ventana<br> <br> el método <tt>alert</tt> sirve para: <br> <input TYPE="radio" NAME="Respuesta3" VALUE="mal"> hacer sonar un pitido de alarma <br> <input TYPE="radio" NAME="Respuesta3" VALUE="bien"> lanzar una ventana con información <br> <input TYPE="radio" NAME="Respuesta3" VALUE="mal"> avisar al navegador de que hay un problema<br> <br> <input TYPE="submit" VALUE="Quiero saber mi nota"> </p> </form></body> </html> Figura 3-5 : Examen 3-13 Tecnología Web 3.2.4 VBScript Podemos definir VBScript como un subconjunto de instrucciones de Visual Basic, pensado para escribir scripts y/o pequeñas funciones. Al igual que el resto de lenguajes de script, VBScript trabaja con los objetos que podemos encontrar en la jerarquía de un navegador Web (en este caso, la jerarquía definida por Microsoft para su plataforma Internet Explorer); para trabajar con dichos objetos, utiliza los métodos, propiedades y eventos de que dispone cada uno de ellos. <HTML> <HEAD> <TITLE>Ejemplo de formularios con Visual Basic</TITLE> <script language="VBScript"> function notas_OnSubmit if document.notas.dni.value = "" then msgbox ("Debes darme tu dni !") notas_OnSubmit = false else notas_OnSubmit = true end if end function </script> </HEAD> <BODY> <FORM NAME="notas" METHOD="POST" ACTION="/cgi_bin/notas.exe"> DNI: <INPUT NAME="dni" TYPE="text"> <BR><HR><INPUT TYPE="submit" VALUE="consulta"> </FORM> </BODY> </HTML> En el ejemplo que se muestra puede verse el código necesario para validar un formulario similar al usado en el ejemplo de JavaScript. En ambos casos tenemos un formulario con un campo de texto donde el usuario debe teclear su DNI para que sea enviado al servidor. Si el campo está vacío se presenta un mensaje indicando al usuario que debe dar su DNI. En VBScript existen varios métodos para asociar a un evento generado por un control una función que lo procese. En el ejemplo se ha optado por uno de ellos que consiste en seguir unas reglas de nombrado de las funciones con el siguiente patrón: <nombre control>_<nombre evento>. En el ejemplo la función se llama notas_OnSubmit de forma que se ejecutará cuando el control notas genere el evento OnSubmit, evento que se genera al pulsar el botón correspondiente. Si la función retorna TRUE los datos del formulario se enviarán al servidor, en caso contrario no se envían. Al formulario se le da nombre con el atributo NAME. 3-14 Programación en el lado del cliente 3.3 Java. Plataforma y lenguaje 3.3.1 Introducción Java es un lenguaje de programación, desarrollado por Sun Microsystems en 1995, que ha venido a revolucionar el mercado de los lenguajes de programación gracias a sus características. Quizás, la mejor definición que se puede hacer de Java es la realizada por la propia Sun Microsystems: "Java es un lenguaje simple, orientado a objetos, robusto, seguro, portable, de alto rendimiento, de arquitectura neutral, interpretado, multi hilo y dinámico" Destacan especialmente los Applets, pequeñas aplicaciones que se ejecutan en entornos web y que permite ejecutar programas obtenidos de la red en el propio ordenador de forma totalmente segura. Los elementos principales de la plataforma de ejecución Java son: 3.3.2 El lenguaje Java: un lenguaje de programación. La Java Platform API: Una librería de clases para la programación de aplicaciones. La Máquina Virtual Java: Una CPU virtual con su propio repertorio de instrucciones. La plataforma de ejecución Java Estrictamente hablado, Java es un lenguaje compilado, pero en realidad Java es a la vez compilado e interpretado. Este es el factor más importante para hacer de Java un lenguaje seguro y portable, esto es, que puede ejecutarse en múltiples plataformas ya que la máquina donde se va a ejecutar la aplicación se encarga de traducir el código Java a código nativo que puede entender el microprocesador. La filosofía que sigue Java es que un programador compila su código fuente utilizando un compilador de Java y obtiene un bytecode (código binario) que es independiente de la plataforma donde se compiló. Este código será más tarde interpretado en un entorno de ejecución que, este sí, debe ser específico de cada plataforma. Este intérprete es conocido como la Máquina Virtual Java. Una vez que estos bytecodes son interpretados, se ejecuta la aplicación. Esta característica multi plataforma ha supuesto una revolución en el mundo de la programación, y una excelente noticia para los programadores. Todo esto implica que el código es código Java sea cual sea la plataforma bajo la que se desarrolla la aplicación o donde ésta se ejecuta. Se puede compilar código fuente en una estación Unix, y ejecutar la aplicación en tres máquinas completamente diferentes Utilizar Java permite que solamente necesite ser mantenido un único código, con la certeza de que funcionará en cualquier plataforma, con el consiguiente ahorro de los costes de desarrollo y mantenimiento que esto supone. 3-15 Tecnología Web Figura 3-6 : Entorno de ejecución Java En el gráfico puede verse como el fichero class con los bytecodes es interpretado por la Máquina Virtual Java ( JVM ). Esta puede estar construida de diversas formas: en forma de interprete o en forma de compilador Just In Time (JIT) que realiza la traducción de los bytecode a código nativo en tiempo de ejecución. 3.3.3 Tipos de aplicaciones Stand - Alone: aplicaciones normales, semejantes a las realizadas con cualquier otro lenguaje y que residen en algún sistema de ficheros accesible por el usuario. Applets: código Java empotrado en páginas HTML descargado desde la red y que se ejecuta en el entorno de un navegador Web. El navegador provee en este caso la JVM. Figura 3-7 : Tipos de aplicaciones 3-16 Programación en el lado del cliente 3.3.3.1 ASPECTOS DE SEGURIDAD Las aplicaciones no tienen restricciones en su ejecución, sin embargo los applets tienen sus privilegios de ejecución muy restringidos. Parece lógico no fiarse de un código descargado de la red y que no estamos seguros de lo que puede hacer. Un applet normal NO1 puede: Acceder al sistema de ficheros local. Lanzar otras aplicaciones. Realizar conexiones a otras máquinas distintas de la cual fue descargado. Apropiarse de forma exclusiva de un recurso local. Figura 3-8 : Gestión de seguridad Como se aprecia en la figura, un código local no tiene ningún tipo de restricción al igual que cualquier otro tipo de aplicación. Un código remoto, por ejemplo un applet, cuyo origen es desconocido o no fiable es sometido a una serie de restricciones. Mediante la firma digital es posible dar al applet acceso total a los recursos del sistema. Figura 3-9 : Firma digital 1 Este NO tan rotundo hay que tomarlo con reservas. Las JVM son programas a menudo con errores de forma que es posible en algunos casos saltarse esas protecciones. 3-17 Tecnología Web 3.3.4 Características del lenguaje 3.3.4.1 Java es un lenguaje orientado a objetos Figura 3-10 : Metodos y propiedades El nucleo de la programación en Java es la clase. Como en otros lenguajes orientados a objeto, la clase encapsula una serie de propiedades y los métodos que permiten manipularlas. Dichas propiedades y métodos pueden ser publicos, siendo estos accesibles desde otras clases, o privados, cuando solo son accesibles desde el interior de la clase. Algo importante a tener en cuenta es que en Java solo se permite una clase publica por fichero, además el nombre del fichero y de la clase deben ser el mismo. public class miClase extends claseBase { private int datoPrivado; public char datoPublico; void miClase() { // Codigo constructor } private int unMetodoPrivado( float arg ) { // Codigo return –1; } public static void main( String[] arg ) { // Metodo main } } Como se aprecia en el ejemplo, la sintaxis, así como los tipos básicos existentes son similares a C/C++. La clase miClase hereda de las propiedades y métodos de claseBase y debe residir en un fichero llamado miClase.java. En java no se permite la herencia múltiple. 3-18 Programación en el lado del cliente 3.3.4.1.1 Métodos especiales Constructores: Se invocan cuando se crea una instancia del objeto mediante el operador new. Tienen el mismo nombre que la clase. Finalizadores: Se invocan cuando se libera la memoria usada por el objeto. Su prototipo es: protected void finalize() { ... } 3.3.4.1.2 Reciclado de memoria En java los objetos tienen un ciclo de vida definido: se crean, se usan y se destruyen. En java un objeto no existe hasta que no se crea una instancia con el operador new. De esta forma la JVM tiene constancia de cuantos objetos existen en cada momento y de si están siendo usados o no. Java usa un gestor de memoria dinámica conocido como recolector de basura ( garbage collector ) que se ocupa de la liberación automática de la memoria ocupada por los objetos que ya no son referenciados, liberando de esta tarea al programador que habitualmente comente errores produciendo fugas de memoria. Objeto obj1 = new Objeto(); Objetos obj2 = new Objeto(); obj1 objeto 1 obj2 objeto 2 obj1 = obj2; obj1 objeto 2 objeto obj2 que objeto 1 será automaticamente liberado 3.3.4.1.3 Bloques Package: La palabra clave package permite agrupar clases e interfaces. Estas clases podrán ser importadas más tarde para ser usadas en otros programas. Import: Los paquetes de clases se cargan con la palabra clave import, import java.util.Date; import java.awt.*; 3-19 Tecnología Web Ejemplo: package TecnologiaWeb.Pilas; class CPila { protected int elementos[]; int cima; public CPila( int tam ) { elementos = new int[ tam ]; cima = 0; } public void MeterEnPila( int dato ) { elementos[ cima ] = dato; cima++; }; } import TecnologiaWeb.Pilas.*; public class Ejemplo { public static void main( String argv[] ) { CPila pila; for ( int i=0; i< argv.length; i++ ) System.out.println( i + “ : ” + argv [i] ); pila = new CPila( 100 ); pila.MeterEnPila( 33 ); } } En el ejemplo se define un paquete llamado tecnologiaWeb.Pilas con una clase llamada CPila que se usa en otra clase llamada Ejemplo. Esto significa: los ficheros fuente se llamadan CPila.java y Ejemplo.java y estarán situados en un directorio de trabajo actual, por ejemplo I:\prueba. Al compilar el fichero CPila.java se creará el fichero CPila.class, pero situado en el directorio TecnologiaWeb\Pilas a partir del directorio actual. Esto es: I:\prueba\TecnologiaWeb\Pilas\CPila.class Al compilar al fichero Ejemplo.java se creará el fichero Ejemplo.class en el directorio actual. Las clases necesarias para el Ejemplo se importan desde el directorio indicado en la llamada import. En este caso <raiz>/TecnologiaWeb/Pilas La variable de entorno CLASSPATH debe contener los path de busqueda a partir de los cuales se buscan las clases. En este caso I:\prueba 3-20 Programación en el lado del cliente 3.3.4.2 Multithread En java podemos crear flujos o hilos de ejecución independientes dentro de un programa Programa Java hilo de ejecución thread Contador de programa Figura 3-11 Procesos y Threads Para ello es suficiente con heredar de la clase Thread. class Motor extends Thread { public void run( ) { for ( ;; ) { // Tareas a realizar // por el thread } } void Motor( ) { … }; } Motor p1 = new Motor(); // Se crea un hilo de ejecucion Motor p2 = new Motor(); // Se crea otro hilo p1.start(); // Se arranca la ejecucion del primero p2.start(); // Se arranca el segundo ::::::::::::::: p1.stop(); p2.stop(); 3.3.4.3 Robusto: excepciones Cuando se dice que Java es robusto se tiende a pensar que no se pueden cometer errores al programar y esto es erróneo. Ciertamente se cometen menos errores que en otros lenguajes, por ejemplo al dejar en manos del sistema (JVM) la liberación automática de la memoria no usada, pero hay más circunstancias a contemplar. 3-21 Tecnología Web Las excepciones no son un mecanismo para prevenir errores, son un mecanismo para que cuando estos se produzcan dar una respuesta o tratamiento correctos a ese error. De hecho hay excepciones que el compilador obliga a tratar y si el programador se ha olvidado o ha intentado hacer la vista gorda no se compilará el programa y se indicará en un mensaje de error cual es la excepción que hay que tratar. Es como si en C el compilador nos obligará a comprobar todos los códigos de retorno que nos dan las funciones y que ha menudo se ignoran. Ejemplo: try { numeros [ i ] = dividendo / divisor; } catch ( ArithmeticExcepction exc ) { System.out.println( “Has divido entre 0” ); System.exit(0); } catch ( ArrayIndexOutOfBoundsExcepction exc ) { System.out.println( “Estas fuera del array” ); System.exit(1); } En el ejemplo se observa la sintaxis a seguir en el tratamiento de excepciones. Hay una cláusula try { } inicial donde va el código susceptible de generar alguna excepción. En este caso se trata de una división cuyo resultado se pretende guardar en una posición de un array. Las dos posibles excepciones son: división entre 0 e índice fuera del array. Cada una de las cláusulas catch captura una excepción y da el tratamiento correspondiente, que en este caso es sacar un mensaje y abortar el programa. Hay que resaltar que todo el mecanismo de excepciones no sirve para nada si una vez producido el error no se le da el tratamiento adecuado. 3-22 Programación en el lado del cliente 3.3.5 Inserción en HTML de Applets Java La etiqueta HTML que permite insertar un applet es la siguiente: <APPLET CODE= WIDTH= HEIGTH= [CODEBASE=] [ALT=] [NAME=] [ALIGN=] [VSPACE=] [HSPACE=]><PARAM NAME= VALUE= ></APPLET> CODE : Indica el fichero de clase ejecutable. No se permite un URL absoluto, aunque sí puede ser relativo al atributo opcional CODEBASE. WIDTH : Indica la anchura inicial que el navegador debe reservar para el applet en pixels. HEIGHT : Indica la altura inicial en pixels. CODEBASE : Se emplea para utilizar el URL base del applet. En caso de no especificarse, se utilizará el mismo que tiene el documento. ALT : Muestra un texto alternativo en caso de no poder presentar el applet. NAME : Otorga un nombre simbólico a esta instancia del applet. ALIGN : Se emplea para alinear el applet permitiendo al texto fluir a su alrededor. VSPACE : Indica el espaciado vertical entre el applet y el texto. HSPACE : Funciona igual que el anterior pero indicando espaciamiento horizontal, en pixels. 3.3.6 Codificación de applets Java La clase base de la que deben heredar los applets es Applet. Un ejemplo de código es el siguiente: import java.applet.*; import java.awt.Graphics; public class Hola extends Applet { String mens; public void init() { mens = getParameter( “mensaje” ); } // init public void paint( Graphics gc ) { gc.drawString( mens, 15, 10 ); } // paint } // Clase 3-23 Tecnología Web Y la etiqueta HTML que permite incluirla en una página podría ser: <APPLET CODE=Hola.class CODEBASE=/applets <PARAM NAME=“mensaje” VALUE=“Como están ustedes” > </APPLET> En el ejemplo aparecen una serie de métodos que es interesante conocer. A continuación se hace una descripción de estos y de otros métodos importantes a la hora de codificar un applet. void init( ) : Este es el punto de arranque del applet. La JVM del navegador llama este método para inicializar el applet. void start() : El navegador llama a este método después de init para comenzar la ejecución del applet. void stop() : El navegador llama a este método para parar la ejecución del applet, por ejemplo si se sale del área de visualización. void destroy () : El navegador llama este método cuando va a descargar el código del applet. Para que vuelva a ejecutarse debe cargarlo de nuevo y llamar a init. void paint(graphics gc ) : El navegador llama este método cada vez que debe repintar el applet. Nunca será llamado directamente por el programador. void repaint() : Forma indirecta de llamar a paint. Cuando se llame a este método el navegador llamará a paint. String getParameter( String nombre ) : Retorna el valor del parámetro en HTML cuyo nombre se pasa, null si el parámetro no existe. void showDocument( URL pagina ) : Sustituye la página actual por la página que se pasa como parámetro. void showDocument( URLpagina, String marco ) : Sustituye la página del marco indicado por la página que se pasa como parámetro. void showStatus( String mensaje ) : Muestra el mensaje en la línea de estado del navegador. 3-24 URL getDocumentBase() : Retorna la URL de la página que contiene el applet. URL getCodeBase() : Retorna la URL del applet. Programación en el lado del cliente 3.3.7 Ejemplo completo A continuación se muestra un ejemplo de applet que actúa como menú. Se dispone de dos marcos: uno con el menú y otro donde se visualiza la selección realizada. 3.3.7.1 Página de marcos <html> <head> <title>Ejemplo de Applet</title> </head> <frameset cols="20%,80%"> <noframes> <body></body> </noframes> <frame name="indice" src="izquierda.htm"> <frame name="principal" src="derecha.htm"> </frameset> </html> 3.3.7.2 Página de menu ( izquierda.htm ) <html><head> <title>Ejemplo de Applets</title></head> <body><h1>Menu</h1> <applet code="Menu.class" codebase="./" width="120" height="100"> <param name="Texto0" value="DIATEL"> <param name="Texto1" value="EUITT"> <param name="Texto2" value="UPM"> <param name="Texto3" value="RedIriS"> <param name="Target0" value="principal"> <param name="Target1" value="principal"> <param name="Target2" value="principal"> <param name="Target3" value="principal"> <param name="URL0" value="http://www.diatel.upm.es"> <param name="URL1" value="http://www.euitt.upm.es"> <param name="URL2" value="http://www.upm.es"> <param name="URL3" value="http://www.rediris.es"> <param name="BGcolor" value="0000FF"> <param name="FGcolor" value="FFFF00"> </applet> </body> </html> El applet leerá los parámetros durante su inicialización y presentará un menú con las opciones que se indican. Cada texto tiene asignada una URL y una página donde se visualizará ( Target ). 3-25 Tecnología Web 3.3.7.3 Código del applet import java.applet.Applet; import java.applet.AppletContext; import java.awt.*; import java.awt.event.*; import java.net.MalformedURLException; import java.net.URL; public class Menu extends Applet { String textos[]; // Texto a presentar en el menu URL enlaces[]; // URL destino de las opciones String targets[]; // Marcos donde se van a presentar int altoTexto; int ancho, alto; Color BGColor, FGColor; Graphics grafico; Image imagen; String tipoLetra; int numPuntos, estilo; int puntosLinea, posicion; /**************** Lee los parametros de la pagina HTML ****************/ void leerParametros() { int i; // Obtengo el numero de textos que van a ser enlaces i=0; while( getParameter( "Texto"+i ) != null ) i++; // Y creo los arrays con ese tamaño textos = new String[ i ]; enlaces = new URL[ i ]; targets = new String[ i ]; for(i=0;i<textos.length;i++) { textos[i] = getParameter( "Texto" + i ); if( getParameter("URL" + i) != null) { try { enlaces[i] = new URL( getParameter("URL" + i)); } catch(MalformedURLException _ex) { 3-26 Programación en el lado del cliente try { enlaces[i]= new URL(getDocumentBase(), getParameter("URL" + i)); } catch(MalformedURLException _ex2) { System.out.println("Enlace no correcto..."); } // catch interno } // catch externo } // if if(getParameter("Target" + i) != null) targets[i] = getParameter("Target" + i); else targets[i] = null; } // for ancho = getSize().width; alto = getSize().height; // Color de fondo if(getParameter("BGColor") != null) BGColor = new Color( Integer.parseInt( getParameter("BGColor"), 16 )); // Color del texto if(getParameter("FGColor") != null) FGColor = new Color( Integer.parseInt( getParameter("FGColor"), 16 )); } // leer paramertros /**************** Inicializacion del applet. ****************/ public void init() { leerParametros(); imagen = createImage( ancho, alto ); grafico = imagen.getGraphics(); puntosLinea = alto / textos.length; // El 0.8 es para que el texto ocupe el 80% del espacio total numPuntos = (int)( puntosLinea * 0.8); grafico.setFont( new Font( tipoLetra, estilo, numPuntos ) ); setBackground( BGColor ); setForeground( FGColor ); posicion = 0; repaint(); // Orden de repintado } 3-27 Tecnología Web /**************** Repintado del applet. La llama el navegador ****************/ public void paint(Graphics g) { update(g); } /**************** Vamos a pintar el menu ****************/ public void update(Graphics g) { int i, CordY, CordX; Color fondo, texto; if ( imagen == null ) return; CordY = (( puntosLinea + numPuntos ) – grafico.getFontMetrics().getDescent())/2; for(i=0;i<textos.length;i++) { // El texto saldra centrado CordX = (ancho-grafico.getFontMetrics().stringWidth(textos[i]))/2; if ( i != posicion ) { fondo = BGColor; texto= FGColor; } else { fondo = FGColor; texto= BGColor; } grafico.setColor ( fondo ); grafico.fillRect (0, i*puntosLinea, ancho, puntosLinea ); grafico.setColor( texto ); grafico.drawString (textos[i],CordX,CordY); CordY += puntosLinea; } // for g.drawImage(imagen, 0, 0, this); } // update 3-28 // Pinta el texto Programación en el lado del cliente /***************** Se llama este metodo cada vez que se pincha sobre el applet. *****************/ public boolean mouseDown(Event e, int x, int y) { posicion= y / puntosLinea; if( enlaces[ posicion ] != null) { if( targets[ posicion ] != null) getAppletContext().showDocument(enlaces[posicion], targets[posicion]); else getAppletContext().showDocument( enlaces[posicion] ); } return true; } // mouseDown /***************** Se llama este metodo cada vez que se entra sobre el area del applet. *****************/ public boolean mouseEnter(Event e, int x, int y) { return mouseMove( e, x, y ); } /***************** Se llama este metodo cada vez que se mueve sobre el area del applet. *****************/ public boolean mouseMove(Event e, int x, int y) { posicion = y / puntosLinea; showStatus( enlaces[ posicion ].toString() ); repaint(); return true; } /***************** Constructor *****************/ public Menu() { estilo = Font.BOLD; tipoLetra = "Times"; } } // Class 3-29 Tecnología Web 3.3.7.4 Apariencia Figura 3-12 : Applet en funcionamiento 3.4 Algunas direcciones interesantes 3-30 http://developer.netscape.com/docs/manuals/communicator/jsguide4 http://www.microsoft.com/Spain/scripting http://java.sun.com