• No se han encontrado resultados

2015 CÁTEDRA DE LENGUAJE DE PROGRAMACIÓN JAVA

N/A
N/A
Protected

Academic year: 2021

Share "2015 CÁTEDRA DE LENGUAJE DE PROGRAMACIÓN JAVA"

Copied!
38
0
0

Texto completo

(1)

2015

CÁTEDRA DE LENGUAJE DE PROGRAMACIÓN JAVA

Ings. Mario Bressano & Miguel Iwanow

(2)

¿Qué es un Servlet? Interacción en Internet

Cuando vamos a un restaurante, el mozo toma el pedido y se lo pasa al personal de la cocina. Al completarse el pedido, el mozo trae la comida. Las actividades que se desarrollan en la cocina, son invisibles para los que realizaron el pedido. La cocina, al igual que la web, opera según un modelo cliente/servidor.

Al escribir la dirección de un sitio web o una URL en un navegador, o cliente, se inicia una petición al servidor que almacena al sitio. Cualquier acción que realice el servidor es transparente para los visitantes del sitio. En una arquitectura cliente/servidor típica de 2-capas, el contenido del sitio web (la capa de presentación del sitio web) como las páginas HTML, los servlets, las JSP, las ASP, software de correo, los scripts CGI, etc., se almacenan en el servidor web.

Los sistemas de 2-capas más viejos, estaban hechos de un servidor web o contenedor, y el navegador.

Figura 1: Arquitectura 2-capas (Cliente/Servidor)

El servidor de aplicaciones es una extensión del modelo cliente/servidor 2-capas a una aproximación de N-capas. El servidor de aplicaciones tiene un servidor o contenedor web integrado y un contenedor de aplicaciones. Un ejemplo es el modelo de aplicaciones J2EE (Edición Empresarial de Java 2). Este modelo es el implementado en servidores de aplicación como el WebSphere de IBM, el BEA WebLogic, Tomcat del Proyecto Jakarta, Sun One Aplication Server; Internet Information Server de Microsoft, etc.

(3)

Figura 2: Arquitectura de N-capas

La aproximación de N-capas es ideal para la generación de contenido dinámico. Los Servlets de Java, que heredan las características de Java y más, han asumido un papel prominente en los servidores de aplicaciones.

¿Qué son los Servlets de Java?

En Java podemos trabajar con Servlet y Java Server Pages (JSP). Los últimos son utilizados cuando la mayoría del contenido que se envía al cliente es texto estático, marcas y solo una pequeña parte de contenido dinámico. En cambio los servlets, son utilizados cuando la cantidad de texto estático y marcas es pequeño. Hay ocasiones en el que el servlet no produce contenido y solo se limita a llamar a otro servlet o JSP.

Podemos decir que los Servlets son componentes del servidor. Estos componentes pueden ser ejecutados en cualquier plataforma o en cualquier servidor debido a la tecnología Java que se usa para implementarlos. Los Servlets incrementan la funcionalidad de una aplicación web. Se cargan de forma dinámica por el entorno de ejecución Java del servidor cuando se necesitan. Cuando se recibe una petición del cliente, el contenedor/servidor web inicia el servlet requerido. El Servlet procesa la petición del cliente y envía la respuesta de vuelta al contenedor/servidor, que es enrutada al cliente.

La palabra Servlet deriva de applet; ésta se refiere a objetos (programas) que se ejecutaban en el contexto de un navegador, mientras que el servlet lo hace en el servidor.

(4)

Figura 3: Modelo de respuesta a peticiones HTTP

La interacción cliente/servidor basada en Web usa el protocolo HTTP. EL protocolo HTTP es un protocolo sin estados basado en un modelo de petición y respuesta con un número pequeño y finito de métodos de petición como GET, POST, HEAD, OPTIONS, PUT, TRACE, DELETE, CONNECT, etc.. La respuesta contiene el estado de la respuesta y meta-información describiendo dicha respuesta. La mayor parte de las aplicaciones web basadas en servlets se construyen en el marco de trabajo del modelo petición/respuesta HTTP.

Los Servlets permiten:

1- Leer datos enviados por los usuarios (formularios web o subprogramas –applet-) 2- Buscar cualquier tipo de información respecto a la petición HTTP (nombre del host,

cookies)

3- General resultados en una conexión a la Db por medio de CORBA (

Common Object

Request Broker Architecture

— arquitectura común de intermediarios en

peticiones a objetos

) O RMI (

Remote Method Invocation

– Llamada a métodos

remotos

) la diferencia consiste en el que el primero permite llamar aplicaciones

escritas en otros lenguajes) 4- Dar formato a los resultados

5- Establecer parámetros HTTP adecuados a la respuestas 6- Devolver el documento al cliente.

Comparación con los CGI (Interfaz de compuerta común) a- EFICIENTES: Pues en los CGI cada petición genera un proceso

(5)

b- ADECUADOS: Analizan y decodifican automáticamente código HTML, cookies, rastrear sesiones, etc.

c- PODEROSOS: Se comunican directamente con el servidor web

d- TRANSPORTABLES: Al estar escritos en Java, poseen un código estándar. e- SEGUROS: Son ejecutados por la máquina virtual con su respectiva seguridad. f- ECONÓMICOS: Para ejecutarse no requiere software propietario.

Requerimientos de Ejecución de los Servlets Java

1. Los Servlets de Java requieren algún conocimiento previo de Java y HTML

2. Las aplicaciones web y las páginas web que requieran iniciación de servlets deben ejecutarse en servidores web con contenedores web integrados, como el servidor web iPlanet o un contenedor solitario de servlets como el Tomcat. Los Servlets también pueden ejecutarse en servidores de aplicación con contenedores web integrados como el Servidor BEA WebLogic.

3. El API Servlet (que tratemos de entender en breve) suele estar mayoritariamente integrado en el servidor/contenedor web. El contenedor/servidor logra esto último implementando la especificación Java Servlet 2.1 o 2.2.

4. Una vez que el contenedor/servidor básico se ha bajado y configurado, el siguiente paso es entender la programación de servlets. El API Servlet tiene dos paquetes, el javax.servlet, que tiene clases y paquetes independientes de protocolos, y el javax.servlet.http, que es más específico para el protocolo HTTP.

Estructura del Servlet y Ciclo de Vida

Antes de meternos en el ciclo de vida de los servlets, necesitamos comprender las clases básicas y los interfaces usados en la implementación del servlet.

Todos los servlets implementan a la interfaz Servlet. El ciclo de vida comienza cuando el servlet se carga en memoria, se invoca a INIT, luego a SERVICE (por cada petición uno, generando un subproceso – ES UNA DIFERENCIA CON EL CGI) y luego al finalizar DESTROY.

(6)

Public Interface Servlet

Todo servlet debe directa o indirectamente implementar este interfaz. Como cualquier otro interfaz de Java, este es también una colección de declaraciones vacías de métodos. Los siguientes métodos están declarados en el interfaz Servlet.

1. public abstract void init (ServletConfig config) throws ServletException.

El método init se usa para inicializar los parámetros proporcionados por el objeto ServletConfig. Se invoca sólo una vez, a menos que el servlet sea reiniciado si se destruye y se vuelve a cargar. El método init es el lugar en el que inicializar los parámetros de configuración como la conexión con una base de datos, la inicialización de archivos y otros valores de entorno. Ninguno método del servlet puede ser invocado a no ser que el servlet esté inicializado mediante el uso del método init().

2. public abstract ServletConfig getServletConfig ()

Este método proporciona el objeto ServletConfig para la inicialización de los parámetros del servlet. Se pueden crear parámetros adicionales especificándolos en el archivo servlet.properties. Una vez que hayan sido especificados en este archivo, se puede acceder a ellos usando el objeto ServletConfig.

3. public abstract void service (ServletRequest req, ServletResponse res) throws ServletException, IOException.

El método service es el punto esencial del modelo petición respuesta del protocolo HTTP. Recibe una petición del cliente en forma de objeto ServletRequest. Los parámetros del cliente son pasados junto al objeto de petición (aunque existen otras formas de enviar parámetros desde el cliente al servlet, por ejemplo, usando cookies o por medio de una reescritura del URL). La respuesta resultante se envía al cliente usando el objeto ServletResponse.

4. public abstract String getServletInfo()

Este método se usa para la extracción de metadatos del servlet, como por ejemplo el autor, la versión del servlet, y otra información concerniente al copyright. El método tendrá que ser redefinido dentro del servlet para que devuelva esta información.

(7)

5. public abstract void destroy ()

El método destroy se invoca para liberar todos los recursos solicitados como la base de datos, y otros recursos del servidor. También se encarga de la sincronización de cualquier hilo pendiente. Este método se llama una sola vez, automáticamente, como el método init.

La clase GenericServlet proporciona una implementación básica del interfaz Servlet. Para escribir un servlet especificamente para el protocolo HTTP, se usa la clase HTTPServlet, que extiende a Generic Servlet.

1. El método destroy se invoca para liberar todos los recursos solicitados como la base de datos, y otros recursos del servidor. También se encarga de la sincronización de cualquier hilo pendiente. Este método se llama una sola vez, automáticamente, como el método init.

La clase GenericServlet proporciona una implementación básica del interfaz Servlet. Para escribir un servlet especificamente para el protocolo HTTP, se usa la clase HTTPServlet, que extiende a Generic Servlet.

Figura 4: Clases Relevantes de Servlets e Interfaces.

Como se ha tratado previamente, el ciclo de vida de los eventos para un servlet se especifica en el interfaz javax.servlet.Servlet. Todos los servlets siguen el modelo del ciclo de vida. El contenedor web tiene la responsabilidad de crear una instancia del servlet y de invocar al método init (1). Si un cliente ha enviado una petición al contenedor web, entonces, esa petición se pasa al método servicio del servlet (2), y se envia una respuesta de vuelta al contendor web (3). Finalmente, cuando el servlet haya finalizado su propósito, el contenedor web invoca al método destroy (4).

(8)

Figura 5: Ciclo de Vida del Servlet web.xml.

web.xml es un archivo escrito en XML que describe diversas características del archivo WAR, a continuación se describen sus elementos básicos.

<web-app> <servlet> <servlet-name>hola</servlet-name> <servlet-class>com.osmosislatina.Saludos</servlet-class> </servlet> <servlet-mapping> <servlet-name>hola</servlet-name> <url-pattern>/visitas</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>hola</servlet-name> <url-pattern>/despedida</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>hola</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping>

(9)

<welcome-file-list> <welcome-file>index.jsp</welcome-file> <welcome-file>index.html</welcome-file> <welcome-file>bienvenida.jsp</welcome-file> </welcome-file-list> </web-app>

El primer elemento <web-app> indica el inicio de la aplicación, es dentro de este elemento que se definen todos los elementos restantes.

El elemento <servlet> define las características de un Servlet y a su vez está compuesto por los elementos <servlet-name> y <servlet-class> que indican un nombre corto para el Servlet así como el nombre de la Clase Java que contiene el Servlet respectivamente. En este caso se indica que la Clase llamada com.osmosislatina.Saludos (encontrada dentro de /WEB-INF/classes) será denominada con el nombre hola.

Posteriormente se define el elemento <servlet-mapping> el cual define la ubicación en términos de directorios de un sitio (URL), esto es, el elemento <servlet-name>hola</servlet-name> esta indicando que el Servlet llamado hola será accesado cada vez que se accese el directorio base /visitas .

Nótese que existen otras dos declaraciones con el Servlet hola, lo anterior permite que un mismo Servlet sea accesado de diversos directorios en un sitio, en este caso se esta indicando que toda solicitud destinada para los URL's /visitas, /despedida y todas aquellas terminadas en *.do sean procesados por el Servlet en cuestión (hola) .

Finalmente el elemento <welcome-file-list> indica que cuando se solicite cualquier directorio sin indicar un archivo en especifico se envíe el archivo llamado: index.jsp, index.html o index.htm, donde el primero tiene preferencia en caso de existir más de un archivo en la lista.

Lo anterior son solo los parámetros básicos utilizados en web.xml, a continuación se describen otros elementos que pueden ser empleados en web.xml

EJEMPLO DE SERVLETS:

Ejemplo 1: Servlet sencillo que va a generar solo texto:

import java.io.PrintWriter; import java.io.IOException;

(10)

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class PrimerServlet extends HttpServlet {

private static final long serialVersionUID = 1L;

public void doGet(HttpServletRequest pedido, HttpServletResponse respuesta) throws ServletException, IOException {

PrintWriter out= respuesta.getWriter();

out.println("Este es mi primer Servlet que genera solo texto"); }

}

private static final long serialVersionUID = 1L: Las clases que implementan este interfaz

son susceptibles de ser serializadas (es decir, las instancias de estas clases pueden guardarse y leerse en/de disco -o cualquier otro dispositivo de entrada/salida-). Simplificando mucho la lógica de serialización, lo que sucede es que los atributos del objeto se convierten en cadenas de bytes y se guardan en el disco. Para leer un objeto, se leen las cadenas de bytes y se reconstruye el objeto a partir de ellos. Imagina que tienes una aplicación que serializa en disco una serie de objetos al cerrarse y los lee en la siguiente ejecución para mantener los valores que tenían antes. En un momento dado, modificas una de las clases añadiendo un atributo nuevo. Al ejecutar esta versión de la aplicación por primera vez, intentará leer de disco los objetos que fueron serializados... pero falta un campo en los objetos de la clase que has modificado (cuando se serializaron el campo no existía) y tu aplicación "teóricamente" va a leer datos corruptos puesto que "teóricamente" no puede saber que la clase ha cambiado (veremos que si puede saberlo). El campo serialVersionUID es el número de versión de la clase. Cuando el objeto es serializado lo primero que hace es escribir el serialVersionUID. Si al leer el objeto se dectecta que el valor del serialVersionUID guardado no coincide con el actual se lanza una exception InvalidClassException, de modo que el programador puede tratar la excepción de manera adecuada (por ejemplo, creando un objeto por defecto para substituir al que no puede leerse).

Para que este mecanismo funcione bien, el programador debe proveer el campo private static final long serialVersionUID en todas las clases que implementen Serializable y en todas las subclases de ellas (este es tu caso). El valor es indiferente, pero debes actualizarlo cada vez

(11)

que modificas tu clase añadiendo o quitando atributos (lo más sencillo en incrementarlo en 1). Si el programador no indica este campo la JVM añade uno por su cuenta, sin embargo no es demasiado conveniente permitir esto (al cambiar ligeramente el programa o cambiar la JMV podría cambiar el valor y darte una desagradable sorpresa)

CLASE HttpServlet

public class PrimerServlet extends HttpServlet {: Los servlets basados en Web

generalmente extienden a la clase HttpServlet que redefine el método Service para las dos peticiones más comunes del HTTP: get y post.

Una petición GET obtiene información del servidor recuperando la misma en un documento HTML o una imagen.

En cambio una petición POST publica o envía datos de un servidor. Dentro de la clase HttpServlet existen estos métodos:

1. doDelete (borrar archivos) 2. doHead (procesar encabezados)

3. doOptions (devuelve información al cliente sobre el servidor) 4. doPut (almacena archivos)

5. doTrace (depuración)

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {:

Los métodos doGet y doPost reciben argumentos HttpServletRequest request,

HttpServletResponse response.

Interfaz HttpServlet request

El servidor web que ejecuta al servlet crea un objeto de este tipo que se lo pasa al método Service que a su vez se lo pasa a doGet o doPost según corresponda, conteniendo la petición del cliente. Por otra parte se invoca throws ServletException, IOException que se ejecutarán:

(12)

String getParameter(String nombre): Nos devuelve el valor del parámetro cuyo nombre le indicamos. Si la variable no existiera o no tuviese ningún valor, devolvería null

Enumerate getParameterNames(): Nos devuelve una enumeración de los nombres de los

parámetros que recibe el servlet.

Enumerate getParameterValues(String): Nos devuelve los valores que toma un parámetro

dado, esto es útil para listas de selección múltiple donde un parámetro tiene más de un valor.

Cookies[].getCookies(): Devuelve arreglo con todos los valores de las cookies que

identifican cliente de una manera única con el servidor Interfaz HttpServlet response.

Esta interfaz permite dar respuesta al cliente. Aquí encontramos:

void.addCookie (Cookie, cookie): agrega objeto cookie al encabezado de respuesta del

cliente

ServletOutputStream.getOutputStream(): Genera un flujo de salida en bytes.

PrintWriter.getWriter (): Flujo de salida en caracteres.

void setContentType(String tipo): Por ejemplo si tipo es MIME, devuelve un archivo HTML.

Ejemplo 2: Servlet que genera código HTML

import java.io.PrintWriter; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class SegundoServlet extends HttpServlet {

private static final long serialVersionUID = 1L;

public void doGet(HttpServletRequest pedido, HttpServletResponse respuesta) throws ServletException, IOException {

respuesta.setContentType("text/html"); PrintWriter out=respuesta.getWriter();

String docType = "<! DOCTYPE HTML PUBLIC \\*-//W3C//DTS HTML 4.0 "+"Transitional//EN\">\n ";

(13)

out.println(docType+ "<HTML>\n"+

"<HEAD><TITLE>PÁGINA WEB GENERADA POR SERVLET</TITLE></HEAD>"+ "<BODY>\n"+ "<H1><CENTER>PRUEBA DE TEXTO</CENTER></H1>"+ "</BODY>\n"+ "</HTML>\n"); } }

Ejemplo 3: Uso de un archivo HTML para llamar a un servlet que genera código HTML.

<!ARCHIVO FORMULARIO0.HTML>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html> <head>

<title>Manejo de una petición Get de HTTP</title> </head>

<body>

<form ACTION="http://localhost:8084/Servlet/CeroServlet" method = "get"> <p><label>Haga clic en el botón para invocar el servlet

<input type = "submit" value = "Obtener documento de HTML" /> </label></p> </form> </body> </html> //ARCHIVO CEROSERVLET.JAVA import javax.servlet.*; import javax.servlet.http.*; import java.io.*;

(14)

protected void doGet( HttpServletRequest peticion, HttpServletResponse respuesta )

throws ServletException, IOException {

respuesta.setContentType( "text/html" ); PrintWriter salida = respuesta.getWriter();

salida.println( "<?xml version = \"1.0\"?>" );

salida.println( "<!DOCTYPE html PUBLIC \"-//W3C//DTD " + "XHTML 1.0 Strict//EN\" \"http://www.w3.org" +

"/TR/xhtml1/DTD/xhtml1-strict.dtd\">" );

salida.println( "<html xmlns = \"http://www.w3.org/1999/xhtml\">" );

salida.println( "<head>" );

salida.println( "<title>Un ejemplo de servlet simple</title>" ); salida.println( "</head>" );

salida.println( "<body>" );

salida.println( "<h1>¡Bienvenido a los servlets!</h1>" ); salida.println( "</body>" );

salida.println( "</html>" );

salida.close(); // cerrar flujo para completar la página }

}

Si llamamos un servlet desde un formulario HTML, podremos hacerlo de dos formas: GET y POST. Con la primera los parámetros del formulario están incluidos la url que se utiliza para invocar el servlet y en el segundo caso los parámetros se almacenan en un buffer especial del servidor.

Para procesar el primer tipo de peticiones (GET) está el método doGet mientras que para el segundo tenemos el método doPost . La implementación por defecto del método service es capaz de determinar el tipo de petición HTTP que en un momento dado recibe el servlet. Una vez identificada llama o al método doGet o al doPost según el caso.

Ejemplo 4: Uso de doGet y doPost

Podemos observar que el método init es público, no devuelve ningún tipo (void), que puede lanzar una excepción (ServletException) y que tiene un parámetro (ServletConfig conf). De estos dos últimos aspectos (excepción y parámetro) no nos tenemos que preocupar pues es el servidor quien ejecuta el método init. En el peor de los casos, tendríamos que lanzar la excepción (si sabemos hacerlo), si por algún motivo el método init que nosotros implementemos falle (por ejemplo, que no se pueda conectar a la base de datos y evitamos mostrar un mensaje de error)

(15)

Lo siguiente que hacemos redefinir el método service, cuando el servidor web recibe una petición para un servlet llama al método public void service(HttpServletRequest req, HttpServletResponse res) con dos parámetros: el primero, de la clase HttpServletRequest, representa la petición del cliente y el segundo, de la clase HttpServletResponse, representa la respuesta del servidor (del servlet, más concretamente).

Archivo GetPostJava.java import javax.servlet.*; import javax.servlet.http.*; import java.io.*;

public class GetPostJava extends HttpServlet {

public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException

{

res.setContentType("text/html"); PrintWriter out = res.getWriter(); out.println("<html>");

out.println("<body>");

out.println("<h1>LLAMADA POR GET</h1>"); out.println(req.getParameter("nombre")); out.println("</body>");

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

public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException

{

res.setContentType("text/html"); PrintWriter out = res.getWriter(); out.println("<html>");

out.println("<body>");

out.println("<h1>LLAMADA POR POST</h1>"); out.println(req.getParameter("nombre")); out.println("</body>");

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

}

Formulario que llama a GetPostJava <html>

<body>

<h1>Método GET Y POST</h1>

<form method="GET" action="http://localhost:8084/Servlet/GetPostJava"> <table border=1>

(16)

<tr><td>Nombres:</td><td><input name="nombre" type="text" style="width: 474px" /></td>

</tr>

<tr><td colspan=2><input type="submit" value="Enviar datos por get"></td></tr> </table>

</form>

<form method="POST" action="http://localhost:8084/Servlet/GetPostJava"> <table border=1>

<tr><td>Nombres:</td><td><input name="nombre" type="text" style="width: 474px" /></td>

</tr>

<tr><td colspan=2><input type="submit" value="Enviar datos por post"> </td></tr> </table>

</form> </body> </html>

Ejemplo 6: Uso de doPost implementado con doGet

import java.io.IOException; import java.io.PrintWriter;

import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;

public class servletDopost extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {

private static final long serialVersionUID = 1L;

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

PrintWriter out;

out = response.getWriter();

response.setContentType("text/html"); out.println("<html>");

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

out.println("Este es mi Primer Servlet"); out.println("</body></html>"); }

(17)

public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {

doPost(req,res); } }

Ejemplo 7: Contar peticiones realizadas

Cuando se crea un servlet, el servidor llama al método init y cada vez que un cliente acceda al servlet el servidor llamará al método service que se encargará de redirigir la llamada

doGet o a doPost. Esto nos quiere decir que cuando se llama por primera vez a un servlet se

ejecutara primero init y después service, pero ... ¿Y la segunda vez y sucesivas también se llama a init o sólo a service?.

Normalmente, el servidor crea el servlet (llama, por tanto, al método init) y lo mantiene funcionando, si ha pasado un tiempo suficiente (y que puede ir desde unos segundos a nunca) sin que el servlet se llame lo deja de ejecutar. Es decir, un servlet se empieza a ejecutar con la primera llamada y, normalmente, se seguirá ejecutando.

De esta forma, vamos a crear un servlet que cuente el número de visitas que recibe, para ello nos bastará crear una variable contador que inicializaremos en el método init y que incrementaremos en doPost/doGet. Por lo que, el contador se inicializará cuando se llame por primera vez al servlet y se irá incrementando en llamadas sucesivas

//Archivo contador.java import javax.servlet.*; import javax.servlet.http.*; import java.io.*;

public class contador extends HttpServlet { //variable contador

int contador;

public void init(ServletConfig conf) throws ServletException { super.init(conf);

//inicializamos la variable contador contador = 1;

}

public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {

(18)

PrintWriter out = res.getWriter(); int tmp = contador;

//incrementamos la variable contador contador++; out.println("<html>"); out.println("<body>"); out.println("<h1>Numero de peticiones " + tmp +"</h1>"); out.println("</body>"); out.println("</html>"); }

public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {

doGet(req, res); }

}

Un mismo servlet puede ser llamado por más de un cliente a la vez. En este caso, el servidor crea una hebra del servlet por cada petición y esas dos hebras accederán concurrentemente a los mismos datos (la variable contador). Como la lectura e incremento de contador no es una operación atómica, se podría utilizar la primitiva de sincronización syncronized para que se realice de forma atómica:

//Archivo Contador2 import javax.servlet.*; import javax.servlet.http.*; import java.io.*;

public class Contador2 extends HttpServlet { //variable contador

int contador;

(19)

throws ServletException { super.init(conf);

//inicializamos la variable contador contador = 1;

}

public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {

res.setContentType("text/html"); PrintWriter out = res.getWriter(); int tmp;

synchronized(this) { //leemos el contador tmp = contador;

//incrementamos la variable contador contador++; } out.println("<html>"); out.println("<body>"); out.println("<h1>Numero de peticiones " + tmp +"</h1>"); out.println("</body>"); out.println("</html>"); }

public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {

doGet(req, res); }

}

Ejemplo 8: Uso de un servlet para redireccionado de páginas en Internet.

(20)

1- Con una página htm que por medio de hipervínculos me dirija al lugar deseado <!—Archivo redireccion.htm-->

<?xml version = "1.0"?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns = "http://www.w3.org/1999/xhtml"> <head>

<title>Redireccionar una petición hacia otro sitio</title> </head>

<body>

<p>Haga clic en un vínculo para redireccionarlo a la página apropiada</p> <p>

<a href = "http://localhost:8084/Servlet/Redireccion?pagina=mario"> www.mariobressano.com.ar</a><br />

<a href = "http://localhost:8084/Servlet/Redireccion?pagina=primera"> Servlet de bienvenida</a>

</body> </html>

2- Por medio de un formulario que me permita seleccionar el lugar deseado <!—Archivo formulario4.htm-->

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml">

<head>

<meta http-equiv="Content-Language" content="es-ar" />

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>FORMULARIO PARA ENVÍO DE DATOS A</title>

<style type="text/css"> .style1 { font-family: Tahoma; font-size: large; text-align: center; } .style2 {

(21)

color: #000080; } .style6 { font-family: Tahoma; font-size: small; } </style> </head> <body>

<p class="style1">REDIRECCION POR FORMULARIO</p>

<form method="get" action="http://localhost:8084/Servlet/Redireccion"> <table style="width: 100%"> <tr> <td class="style6" colspan="2"> <hr style="height: -71px" class="style2" /></td> </tr> <tr> </tr><tr></tr><tr></tr><tr> </tr> <tr> </tr> <tr>

<td style="width: 159px" class="style6">Indicar Página</td> <td class="style6">

<table style="width: 658px"> <tr>

<td style="width: 218px">

<input name="pagina" type="radio" checked="checked" value="mario" />MARIOBRESSANO</td>

<td style="width: 219px">

<input name="pagina" type="radio" value="primera" />PRIMERA</td><td style="width: 219px"></td>

</tr> </table> </td> </tr>

(22)

<tr>

<td class="style6" valign="top" colspan="2"> <hr style="height: -71px" class="style2" /></td> </tr>

<tr>

<td class="style6" valign="top" colspan="2"> <table align="center">

<tr>

<td></td>

<td><input name="Submit1" type="submit" value="Enviar datos" /></td> </tr> </table> </td> </tr> </table> </form> </body> </html>

//Servlet para redireccionar –Archivo Redireccion.java import javax.servlet.*;

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

public class Redireccion extends HttpServlet {

protected void doGet( HttpServletRequest peticion, HttpServletResponse respuesta ) throws ServletException, IOException

{

String ubicacion = peticion.getParameter( "pagina" ); if ( ubicacion != null ) if ( ubicacion.equals( "mario" )) respuesta.sendRedirect( "http://www.mariobressano.com.ar" ); else if ( ubicacion.equals( "primera" ) ) respuesta.sendRedirect( "CeroServlet" );

(23)

// código que se ejecuta solamente si este servlet // no redirecciona al usuario hacia otra página respuesta.setContentType( "text/html" ); PrintWriter salida = respuesta.getWriter(); // empezar documento de XHTML

salida.println( "<?xml version = \"1.0\"?>" );

salida.println( "<!DOCTYPE html PUBLIC \"-//W3C//DTD " + "XHTML 1.0 Strict//EN\" \"http://www.w3.org" +

"/TR/xhtml1/DTD/xhtml1-strict.dtd\">" ); salida.println(

"<html xmlns = \"http://www.w3.org/1999/xhtml\">" ); // sección de encabezado del documento

salida.println( "<head>" );

salida.println( "<title>Página inválida</title>" ); salida.println( "</head>" );

// sección del cuerpo del documento salida.println( "<body>" );

salida.println( "<h1>Solicitó una página inválida</h1>" ); salida.println( "<p><a href = " +

"\"redireccion.html\">" );

salida.println( "Haga clic aquí para seleccionar de nuevo</a></p>" ); salida.println( "</body>" );

// fin del documento de XHTML salida.println( "</html>" );

salida.close(); // cerrr flujo para completar la página }

}

Ejemplo 9: Uso de un servlet para levantar datos de un formulario confeccionado en html

<!Archivo formulario.htm>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML>

<HEAD><TITLE>Formulario para ingreso de datos</TITLE></HEAD> <BODY BGCOLOR="#000000" text="#FFFFFF">

(24)

<P></P>

<H2>Introduce tus datos:</H2><BR> <HR></HR>

<CENTER>

<FORM ACTION="http://localhost:8084/Servlet/Tercerservlet" METOD="POST"> <TABLE BORDER>

<TR>

<TD><B>Nombre:</TD>

<TD><INPUT TYPE=TEXTBOX NAME="NOM" SIZE="25" VALUE=""></TD> </TR>

<TR>

<TD><B>Edad:</TD>

<TD><INPUT TYPE=TEXTBOX NAME="EDA" SIZE="20" VALUE=""></TD> </TR>

</TABLE> <P></P>

<INPUT TYPE=SUBMIT VALUE="Enviar"> <HR></HR> <b><small>Formulario de Datos</small></b></FORM><b> </CENTER> </BODY> </HTML> //Archivo Tercerservlet.java import java.io.*; import javax.servlet.*; import javax.servlet.http.*;

public class Tercerservlet extends HttpServlet { private static final long serialVersionUID = 1L;

public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {

(25)

PrintWriter pw = res.getWriter();

pw.println("<HTML><HEAD><TITLE>Leyendo parámetros</TITLE></HEAD>");

pw.println("<BODY BGCOLOR=\"#CCBBAA\">");

pw.println("<H2>Leyendo parámetros desde un formulario html</H2><P>"); pw.println("<UL>\n");

pw.println("Te llamas " + req.getParameter("NOM") + "<BR>"); pw.println("y tienes " + req.getParameter("EDA") + " años<BR>"); pw.println("</BODY></HTML>");

pw.close(); }

public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {

doGet(req,res); } }

Normalmente los servlets tendrán parámetros o fuentes de información que le darán su aspecto dinámico. Es decir, para generar una simple página HTML no nos complicamos tanto la vida, se escribe la página HTML y se ha terminado. Las fuentes de información de las que un servlet hace uso, pueden ser varias: el propio servlet, el servidor web, ficheros o bases de datos a los que pueda acceder o parámetros que le pase el cliente. De todas estas fuentes, nos interesan los accesos a bases de datos que veremos más adelante y los parámetros que nos pasa el cliente mediante formularios HTML.

Cuando pasamos parámetros a través de un formulario, en los Servlets a través de la clase

ServletRequest, disponemos de los siguientes métodos para su tratamiento:

String getParameter(String nombre): Nos devuelve el valor del parámetro cuyo

nombre le indicamos. Si la variable no existiera o no tuviese ningún valor, devolvería null

Enumerate getParameterNames(): Nos devuelve una enumeración de los nombres

de los parámetros que recibe el servlet.

Enumerate getParameterValues(String): Nos devuelve los valores que toma un

parámetro dado, esto es útil para listas de selección múltiple donde un parámetro tiene más de un valor

(26)

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml">

<head>

<meta http-equiv="Content-Language" content="es-ar" />

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>FORMULARIO PARA ENVÍO DE DATOS A</title>

<style type="text/css"> .style1 { font-family: Tahoma; font-size: large; text-align: center; } .style2 { color: #000080; } .style6 { font-family: Tahoma; font-size: small; } </style> </head> <body>

<p class="style1">FORMULARIO PARA ENVÍO DE DATOS A SERVLET:</p> <form method="post" action="http://localhost:8084/Servlet/CuartoServlet"> <table style="width: 100%"> <tr> <td class="style6" colspan="2"> <hr style="height: -71px" class="style2" /></td> </tr> <tr> <td style="width: 159px" class="style6">Nombres</td> <td class="style6">

<input name="nombres" type="text" style="width: 474px" /></td> </tr>

(27)

<tr>

<td style="width: 159px" class="style6">Apellido</td> <td class="style6">

<input name="apellido" type="text" style="width: 474px" /></td> </tr>

<tr>

<td style="width: 159px" class="style6">Domicilio</td> <td class="style6">

<input name="domicilio" type="text" style="width: 474px" /></td> </tr>

<tr>

<td style="width: 159px" class="style6">Teléfono</td> <td class="style6">

<input name="telefono" type="text" style="width: 474px" /></td> </tr>

<tr>

<td style="width: 159px" class="style6">E-mail</td> <td>

<input name="email" type="text" style="width: 474px" /></td> </tr>

<tr>

<td style="width: 159px" class="style6">Tarjeta de Crédito</td> <td class="style6">

<table style="width: 658px"> <tr>

<td style="width: 218px">

<input name="nombre tarjeta" type="radio" checked="checked" value="VISA" />VISA</td>

<td style="width: 219px">

<input name="nombre tarjeta" type="radio" value="MASTERCARD" />MASTERCARD</td>

<td style="width: 219px">

<input name="nombre tarjeta" type="radio" value="AMERICAN EXPRESS" />AMERICAN

EXPRESS</td> </tr>

(28)

</table> </td> </tr>

<tr>

<td style="width: 159px" class="style6" valign="top">Observaciones</td> <td class="style6">

<textarea name="OBSERVACIONES" style="width: 478px; height: 140px"></textarea></td>

</tr> <tr>

<td class="style6" valign="top" colspan="2"> <hr style="height: -71px" class="style2" /></td> </tr>

<tr>

<td class="style6" valign="top" colspan="2"> <table align="center">

<tr>

<td><input name="Reset1" type="reset" value="Borrar Datos" /></td>

<td><input name="Submit1" type="submit" value="Enviar datos" /></td> </tr> </table> </td> </tr> </table> </form> </body> </html>

//Archivo CuartoServlet.java- Levanta datos del formulario anterior import java.io.*;

import java.util.*; import javax.servlet.*;

(29)

import javax.servlet.http.*;

public class CuartoServlet extends HttpServlet { private static final long serialVersionUID = 1L;

public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {

res.setContentType("text/html"); PrintWriter out = res.getWriter();

String docType = "<! DOCTYPE HTML PUBLIC \\*-//W3C//DTS HTML 4.0 "+"Transitional//EN\">\n ";

out.println(docType+ "<HTML>\n"+

"<HEAD><TITLE>PÁGINA WEB GENERADA POR SERVLET</TITLE></HEAD>"+

"<BODY BGCOLOR=\"#CCBBAA\">\n"+ "<H1><CENTER>LECTURA DE DATOS DEL FORMULARIO</CENTER></H1>\n"+

"<BR>\n"+

"<TABLE BGCOLOR=\"#FFFFFF\" BORDER=0>\n"+

"<TR><TH>NOMBRE DEL CAMPO<TH>VALOR DEL CAMPO"); Enumeration nombresCampo = req.getParameterNames(); while (nombresCampo.hasMoreElements()){

String nombreCampo =(String)nombresCampo.nextElement(); out.print("<TR><TD>"+nombreCampo+"\n<TD>");

String[] contenidosCampo = req.getParameterValues(nombreCampo); if (contenidosCampo.length==1)

{

String contenidoCampo = contenidosCampo[0]; if (contenidoCampo.length()==0){ out.println("<i>Sin Valor</I>"); } else { out.println(contenidoCampo);

(30)

} }

else {

out.println("<UL>");

for (int i=0; i<contenidosCampo.length;i++) { out.println("<LI>"+contenidosCampo[i]); } out.println("</UL>"); } } out.println("</table></BODY></HTML>"); }

public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {

doGet(req,res); } }

En el caso de HttpServlet la implementación por defecto del método service comprueba si la petición recibida era de tipo POST (los parámetros se pasan en la cabecera del mensaje) o de tipo GET (los parámetros están en la URL, luego son visibles para todo el mundo), y llama a los métodos doPost o doGet dependiendo de esto.

Tanto doGet como doPost reciben como parámetros objetos de tipo HttpServletRequest y HttpServletResponse.

ACCESO A BASE DE DATOS

(31)

El problema es comunicar un programa o aplicación con una base de datos y más que comunicar se pretende que el programa o aplicación realice una serie de procesos u operaciones con la base de datos o mejor aun con el conjunto de tablas que contiene una base de datos.

Una base de datos puede estar físicamente en el servidor y en alguna carpeta o directorio del disco duro de dicha máquina.

También es necesario conocer que así como existen servidores de páginas (web server), servidores de correo (mail server), servidores de ftp (ftp server), etc., también existen servidores de bases de datos (database server), los más comunes son el sqlserver de Microsoft, Oracle, Mysql, etc., estos servidores también pueden crear, administrar y procesar una base de datos.

El modo de comunicarse entre nuestro programa o aplicación y la base de datos implica que ambos manejen un lenguaje de programación común, es decir, no se puede mandar una instrucción en C Sharp, o en Basic o Pascal, a la base de datos y además esperar que esta ultima la entienda (una razón muy sencilla es que la base de datos tendría que conocer o comprender todos los lenguajes de programación), para resolver este problema de comunicación es que se usa un lenguaje común de bases de datos que tanto los lenguajes de programación existentes como las bases de datos entienden, este lenguaje común de bases de datos es el SQL (Structured Query Languaje) o lenguaje estructurado de consultas.

Las principales instrucciones de SQL que se son SELECT, INSERT, UPDATE y DELETE. ¿Cómo mandamos las instrucciones SQL a la base de datos?

La respuesta se basa en los siguientes OBJETOS:

OBJETO JDBCODBCDRIVER: Objeto que se utiliza para traducir las instrucciones del

lenguaje SQL a las instrucciones del lenguaje original de la base de datos.

OBJETO CONNECTION: Objeto que se utiliza para establecer una conexión o enlace a la base

de datos.

OBJETO RESULTSET: Es la representación en memoria de una de las tablas de la base de

datos en disco; se puede entender como una tabla virtual, recordar que generalmente todos los procesos que se realicen con la tabla (insertar registros, eliminar registros, etc.) se realizaran

(32)

realmente contra un resulset y no provocan ningún cambio en la tabla física en disco, resulset tiene un conjunto de métodos muy útiles y muy usados para el proceso de los renglones de la tabla virtual.

OBJETO STATEMENT: Este objeto y sus dos métodos executequery (para select de SQL) y

executeupdate (para insert, update y delete de SQL) son los métodos que se utilizaran para comunicarse con la tabla física en disco.

createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATA BLE)

Una de las nuevas características del API JDBC 2.0 es la habilidad de mover el cursor en una hoja de resultados tanto hacia atrás como hacia adelante. También hay métodos que nos permiten mover el cursor a una fila particular y comprobar la posición del cursor. La hoja de resultados Scrollable hace posible crear una herramienta GUI (Interface Gráfico de Usuario) para navegar a través de ella, lo que probablemente será uno de los principales usos de esta característica. Otro uso será movernos a una fila para actualizarla

Antes de poder aprovechar estas ventajas, necesitamos crear un objeto ResultSet Scrollable, por ejemplo:

Statement stmt = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); ResultSet srs = stmt.executeQuery("SELECT COF_NAME, PRICE FROM COFFEES");

El segundo argumento es una de las dos constantes de ResultSet para especificar si la hoja de resultados es de sólo lectura o actualizable: CONCUR_READ_ONLY y CONCUR_UPDATABLE. Lo que debemos recordar aquí es que si especificamos un tipo, también debemos especificar si es de sólo lectura o actualizable. También, debemos especificar primero el tipo, y como ambos parámetros son int, el compilador no comprobará si los hemos intercambiado.

Especificando la constante TYPE_FORWARD_ONLY se crea una hoja de resultados no desplazable, es decir, una hoja en la que el cursor sólo se mueve hacia adelante. Si no se especifican constantes para el tipo y actualización de un objeto ResultSet, obtendremos automáticamente una TYPE_FORWARD_ONLY y CONCUR_READ_ONLY (exactamente igual que en el API del JDBC 1.0).

(33)

Obtendremos un objeto ResultSet desplazable si utilizamos una de estas constantes: TYPE_SCROLL_INSENSITIVE o TYPE_SCROLL_SENSITIVE. La diferencia entre estas dos es si la hoja de resultados refleja los cambios que se han hecho mientras estaba abierta y si se puede llamar a ciertos métodos para detectar estos cambios. Generalmente hablando, una hoja de resultados TYPE_SCROLL_INSENSITIVE no refleja los cambios hechos mientras estaba abierta y en una hoja TYPE_SCROLL_SENSITIVE si se reflejan. Los tres tipos de hojas de resultados harán visibles los resultados si se cierran y se vuelve a abrir. En este momento, no necesitamos preocuparnos de los puntos delicados de las capacidades de un objeto ResultSet, entraremos en más detalle más adelante. Aunque deberíamos tener en mente el hecho de que no importa el tipo de hoja de resultados que especifiquemos, siempre estaremos limitados por nuestro controlador de base de datos y el driver utilizados.

Una vez que tengamos un objeto ResultSet desplazable, srs en el ejemplo anterior, podemos utilizarlo para mover el cursor sobre la hoja de resultados. Recuerda que cuando creábamos un objeto ResultSet anteriormente, tenía el cursor posicionado antes de la primera fila. Incluso aunque una hoja de resultados se seleccione desplazable, el cursor también se posiciona inicialmente delante de la primera fila. En el API JDBC 1.0, la única forma de mover el cursor era llamar al método next. Este método todavía es apropiado si queremos acceder a las filas una a una, yendo de la primera fila a la última, pero ahora tenemos muchas más formas para mover el cursor.

La contrapartida del método next, que mueve el cursor una fila hacia delante (hacia el final de la hoja de resultados), es el nuevo método previous, que mueve el cursor una fila hacia atrás (hacia el inicio de la hoja de resultados). Ambos métodos devuelven false cuando el cursor se sale de la hoja de resultados (posición antes de la primera o después de la última fila), lo que hace posible utilizarlos en un bucle while. Ye hemos utilizado un método next en un bucle while, pero para refrescar la memoria, aquí tenemos un ejemplo que mueve el cursor a la primera fila y luego a la siguiente cada vez que pasa por el bucle while. El bucle termina cuando alcanza la última fila, haciendo que el método next devuelva false. El siguiente fragmento de código imprime los valores de cada fila de srs, con cinco espacios en blanco entre el nombre y el precio.

Statement stmt = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);

ResultSet srs = stmt.executeQuery("SELECT COF_NAME, PRICE FROM COFFEES"); while (srs.next()) {

(34)

String name = srs.getString("COF_NAME"); float price = srs.getFloat("PRICE");

System.out.println(name + " " + price); }

Se puede mover el cursor a una fila particular en un objeto ResultSet. Los métodos first, last, beforeFirst, y afterLast mueven el cursor a la fila indicada en sus nombres. El método absolute moverá el cursor al número de fila indicado en su argumento. Si el número es positivo, el cursor se mueve al número dado desde el principio, por eso llamar a absolute(1) pone el cursor en la primera fila. Si el número es negativo, mueve el cursor al número dado desde el final, por eso llamar a absolute(-1) pone el cursor en la última fila. La siguiente línea de código mueve el cursor a la cuarta fila de srs.

srs.absolute(4);

Si srs tuviera 500 filas, la siguiente línea de código movería el cursor a la fila 497. srs.absolute(-4);

Tres métodos mueven el cursor a una posición relativa a su posición actual. Como hemos podido ver, el método next mueve el cursor a la fila siguiente, y el método previous lo mueve a la fila anterior. Con el método relative, se puede especificar cuántas filas se moverá desde la fila actual y también la dirección en la que se moverá. Un número positivo mueve el cursor hacia adelante el número de filas dado; un número negativo mueve el cursor hacia atrás el número de filas dado. Por ejemplo, en el siguiente fragmente de código, el cursor se mueve a la cuarta fila, luego a la primera y por último a la tercera.

srs.absolute(4); // cursor está en la cuarta fila . . .

srs.relative(-3); // cursor está en la primera fila . . .

srs.relative(2); // cursor está en la tercera fila

El método getRow permite comprobar el número de fila donde está el cursor. Por ejemplo, se puede utilizar getRow para verificar la posición actual del cursor en el ejemplo anterior.

srs.absolute(4);

(35)

srs.relative(-3);

int rowNum = srs.getRow(); // rowNum debería ser 1 srs.relative(2);

int rowNum = srs.getRow(); // rowNum debería ser 3

Existen cuatro métodos adicionales que permiten verificar si el cursor se encuentra en una posición particular. La posición se indica en sus nombres:isFirst, isLast, isBeforeFirst, isAfterLast. Todos estos métodos devuelven un boolean y por lo tanto pueden ser utilizados en una sentencia condicional. Por ejemplo, el siguiente fragmento de código comprueba si el cursor está después de la última fila antes de llamar al método previous en un bucle while. Si el método isAfterLast devuelve false, el cursor no estará después de la última fila, por eso se llama al método afterLast. Esto garantiza que el cursor estará después de la última fila antes de utilizar el método previous en el bucle while para cubrir todas las filas de srs.

if (srs.isAfterLast() == false) { srs.afterLast(); }

while (srs.previous()) {

String name = srs.getString("COF_NAME"); float price = srs.getFloat("PRICE");

System.out.println(name + " " + price); }

Ejercicio 10: Acceso de un servlet a una BD

//Archivo ConexionDB import javax.servlet.*; import javax.servlet.http.*; import java.io.*;

import java.sql.*;

public class ConexionDb extends HttpServlet { Connection conexion = null;

(36)

super.init(conf); }

public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {

res.setContentType("text/html"); PrintWriter out = res.getWriter(); ResultSet tabla= null;

Statement instruccion=null; try {

//Leemos el driver

Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");

String miBasedeDatos ="jdbc:odbc:Driver={Microsoft Access Driver (*.mdb)};" +"DBQ=C:/bases/alumnos2010.mdb";

Connection conn = DriverManager.getConnection(miBasedeDatos); //Decimos que nos hemos conectado

out.println("<html>"); out.println("<body>"); out.println("<h1>¡Hemos conectado!</h1>"); out.println("</body>"); out.println("</html>"); instruccion = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE); }

catch (ClassNotFoundException e1) { //Error si no puedo leer el driver

out.println("ERROR:No encuentro el driver de la BD: "+ e1.getMessage());

}

catch (SQLException e2) { //Error SQL: login/passwd mal

out.println("ERROR:Fallo en SQL: "+e2.getMessage()); }

(37)

//Finalmente desconecto de la BD try {

if (conexion!=null) conexion.close();

} catch (SQLException e3) {

out.println("ERROR:Fallo al desconectar de la BD: "+ e3.getMessage());

}

try { tabla = instruccion.executeQuery("select * from dantealu"); out.println("<TABLE Border=10 CellPadding=5><TR>");

out.println("<th bgcolor=White>NOMBRE</th><th bgcolor=Red>documento</th></TR>"); while(tabla.next()) { out.println("<TR>"); out.println("<TD>"+tabla.getString(1)+"</TD>"); out.println("<TD>"+tabla.getString(2)+"</TD>"); out.println("</TR>"); }; out.println("</TABLE><br>CERRAMOS LA TABLA Y FINALIZAMOS</CENTER></DIV></HTML>"); tabla.close(); } catch(SQLException e) {}; } }

(38)

public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {

doGet(req, res); }

} Bibliografía:

Título: Java. Cómo programar. Quinta Edición Autor: Deitel.

Editorial: Pearson. Pretince Hall

Título: Programación en Java 2

Autor: Luis Aguilar e Ignacio Zahonero Martínez Editorial: Mc. Graw Hill

Título: Programación con Java Autor: Decaer - Hirshfield Editorial: Thompson – Learning

Web: Java en castellano http://www.programacion.com

Referencias

Documento similar

Dentro del mundo de la Web se encuentran diversos productos como Zope, servidor de aplicaciones Web, Python, lenguaje de programación interpretado e interactivo, capaz de

Java es un lenguaje de programación con el que podemos realizar cualquier tipo de programa. En la actualidad es un lenguaje muy extendido y cada vez cobra más importancia tanto en

Descripción: Método que recibe diferentes parámetros del método listar métodos eliminar y devuelve un objeto al método correspondiente en la moduladora.. Nombre: Activar(id :

Se utilizó Java como lenguaje de programación, PostgreSQL 8.3 como servidor de aplicaciones, el framework Hibernate para el acceso a datos, el framework Seam para la unión entre

¿Quién y cuándo se

Cuando el cliente realiza una petición, mediante una opción que indica el método a utilizar para solicitar un recurso (identificado por una URI), el servidor envía

Para terminar esta comunicación, nos gustaría destacar la gran acogida que han tenido las experiencias llevadas a cabo, y en lo que respecta al profesor, como hemos indicado al

&#34;la inspección de la figura (para aquéllos que deseen dibujarla) les indi- cará todas las diferentes posibilidades permitidas por la ecuación&#34; 30. Se puede decir que, en