Download Seleccionar una Tabla

Document related concepts
no text concepts found
Transcript
Taller Aplicaciones Web con JSP
Dante Mendoza Ruelas
Taller de Java Enterprise Edition
Practicas:
Instalación del SDK de java:
 Se descarga de: http://java.sun.com/javaee/downloads/index.jsp
 Se ejecuta
 Al pedir un administrador poner un usuario y clave (comúnmente admin
es usuario)

Se habilita la opción de manejar como un servicio de Windows el
servidor de java.


Se habilita la opción de agregar el path.
Se selecciona la opcion de inicializar el servidor y listo.
Taller Aplicaciones Web con JSP
Dante Mendoza Ruelas
Instalación de Macromedia DreamWeaver:
 Se descarga de: http://www.adobe.com/products/dreamweaver/ en la
sección de free trial.
 Se ejecuta el archivo descargado y se siguen las instrucciones para su
instalación.
JSP
Primero vamos a configurar el entorno de dreamweaver y dar de alta un nuevo
proyecto con los datos del servidor












Se crea la siguiente ubicación
C:\Sun\AppServer\domains\domain1\docroot\tjava\jsp\
Abre el macromedia dreamweaver.
En la primera ventana que aparece ponle en el sitio de dreamweaver.
En el nombre ponle Taller Java.
En la pagina pon http://localhost:8080/tjava/jsp/.
En la siguiente parte selecciona que si quieres usar alguna tecnología
Selecciona jsp.
En la siguiente parte selecciona editar localmente y probar en red.
Selecciona alguna ubicación valida donde se guardaran los archivos.
En la sección siguiente selecciona local y escribe la siguiente ubicación
C:\Sun\AppServer\domains\domain1\docroot\tjava\jsp\
En la siguiente sección escribir la siguiente dirección
http://localhost:8080/tjava/jsp/ y probarla
En la siguiente parte selecciona no y finaliza
Primer Ejercicio (Hola Mundo)
Ahora vamos a crear una pagina jsp
 Le damos en más en la ventana que actualmente aparece, seleccionamos
dinamica y jsp.
 Ahora Ahí tres tipos de etiquetas seleccionamos la de codigo e
insertamos un código dentro de las etiquetas de cuerpo:
<%
out.println("<b>Hola Mundo</b>");
%>

Se guarda y se prueba con el F12
Felicidades ya has creado tu primera pagina con JSP!!!! =)
Taller Aplicaciones Web con JSP
Ejercicio #2:
Combinación de html dinamico y estatico.
Dante Mendoza Ruelas
Vamos a crear una pagina en la cual incluya html dinámico creado por java y
estático; Se trata de hacer una tabla en html y con código java llenarla de dos
maneras con código html y código java embebido o al revés código java con
código html adentro.
Primera opción:
Creamos una nueva página con una tabla e ingresamos el siguiente código java:
<%@ page import="java.util.*"%>
<%
String[] nombres = {"Dante", "De Avila", "Llama", "Vicky", "Oswaldo",
"Monse", "Ciseña", "Cortinas", "Gina", "Tere", "Mayela"};
Random aleatorio = new Random();
int num;
%>
Y en cada celda de la tabla ingresamos:
<td><% num = aleatorio.nextInt(10); out.println(nombres[num]); %></td>
<td><% out.println(num + 1); %></td>
¿Qué es lo que hace?
 Primero generamos un arreglo de nombres
 inicializamos la función de números aleatorios
 generamos una variable entera donde guardaremos el número
aleatorio generado.
 Después en cada celda de la tabla generaremos un numero aleatorio
con el cual obtendremos un nombre y mostraremos el numero
generado
Taller Aplicaciones Web con JSP
Dante Mendoza Ruelas
Segunda opción:
Ahora meteremos codigo html dentro del codigo java:
En una pagina nueva insertamos el siguiente codigo:
<%@ page import="java.util.*"%>
<%
String[] nombres = {"Dante", "De Avila", "Llama", "Vicky", "Oswaldo",
"Monse", "Ciseña", "Cortinas", "Gina", "Tere", "Mayela"};
Random aleatorio = new Random();
int num, num2;
num = aleatorio.nextInt(10);
num2 = num + 1;
out.println("<table width=\"200\" border=\"1\">" +
"<tr>" +
"<td>" + nombres[num] + "</td>" +
"<td>" + num2 + "</td>" +
"</tr>");
num = aleatorio.nextInt(10);
num2 = num + 1;
out.println("<tr>" +
"<td>" + nombres[num] + "</td>" +
"<td>" + num2 + "</td>" +
"</tr>");
num = aleatorio.nextInt(10);
num2 = num + 1;
out.println("<tr>" +
"<td>" + nombres[num] + "</td>" +
"<td>" + num2 + "</td>" +
"</tr>");
num = aleatorio.nextInt(10);
num2 = num + 1;
out.println("<tr>" +
"<td>" + nombres[num] + "</td>" +
"<td>" + num2 + "</td>" +
"</tr>");
num = aleatorio.nextInt(10);
num2 = num + 1;
out.println("<tr>" +
"<td>" + nombres[num] + "</td>" +
"<td>" + num2 + "</td>" +
"</tr>" +
"</table>");
%>
¿Qué es lo que hace?
Primero lo mismo que el pasado ejercicio solo que esta ves usamos el método
out.println no solo para mostrar datos de java si no para mostrar el código de
la tabla también.
Taller Aplicaciones Web con JSP
Ejercicio #2 (parámetros)
Dante Mendoza Ruelas
Manejar Datos de Formularios
Introducción
Si alguna vez has usado un motor de búsqueda Web, visitado un tienda
de libros on-line, etc., probablemente habrás encontrado URLs de búsqueda
divertidas como:
http://host/path?user=Marty+Hall&origin=bwi&dest=lax.
La parte posterior a la interrogación (user=Marty+Hall&origin=bwi&dest=lax) es
conocida como datos de formulario, y es la forma más común de obtener datos
desde una página Web para un programa del lado del servidor. Puede añadirse
al final de la URL después de la interrogación (como arriba) para peticiones
GET o enviada al servidor en una línea separada, para peticiones POST.
Extraer la información necesaria desde estos datos de formulario es
adicionalmente una de las partes más tediosas de la programación CGI Primero
de todo, tenemos que leer los datos de una forma para las peticiones GET (en
CGI tradicional, esto se hace mediante QUERY_STRING), y de otra forma para
peticiones POST (normalmente leyendo la entrada estándard).
Segundo, tenemos que separar las parejas de los ampersands, luego
separar los nombres de los parámetros (a la izquierda de los signos igual) del
valor del parámetro (a la derecha de los signos igual).
Tercero, tenemos que decodificar los valores. Los valores alfanuméricos
no cambian, pero los espacios son convertidos a signos más y otros caracteres
se convierten como %XX donde XX es el valor ASCII (o ISO Latin-1) del carácter,
en hexadecimal. Por ejemplo, si alguien introduce un valor de "~hall, ~gates, y
~mcnealy" en un campo de texto con el nombre "users" en un formulario HTML,
los
datos
serían
enviados
como
users=%7Ehall%2C+%7Egates%2C+and+%7Emcnealy".
Finalmente, la cuarta razón que hace que el análisis de los datos de
formulario sea tedioso es que los valores pueden ser omitidos (por ejemplo,
param1=val1&param2=&param3=val3) y un parámetro puede tener más de un
valor y que el mismo parámetro puede aparecer más de una vez (por ejemplo:
param1=val1&param2=val2&param1=val3).
Una de las mejores características de los servlets Java es que todos estos
análisis de formularios son manejados automáticamente. Simplemente
llamamos al método getParameter de HttpServletRequest, y suministramos el
nombre del parámetro como un argumento. Observa que los nombres de
parámetros son sensibles a la mayúsculas. Hacemos esto exactamente igual que
cuando los datos son enviados mediante GET o como si los enviaramos
mediante POST. El valor de retorno es un String correspondiente al valor
uudecode de la primera ocurrencia del parámetro. Se devuelve un String vacío
si el parámetro existe pero no tiene valor, y se devuelve null si no existe dicho
parámetro. Si el parámetro pudiera tener más de un valor, como en el ejemplo
anterior, deberíamos llamar a getParameterValues en vez de a getParameter.
Este devuelve un array de strings. Finalmente, aunque en aplicaciones reales
nuestras aplicaciones probablemente tengan un conjunto específico de
Taller Aplicaciones Web con JSP
Dante Mendoza Ruelas
nombres de parámetros por los que buscar. Usamos getParameterNames para
esto, que devuelve una Enumeration, cada entrada puede ser forzada a String y
usada en una llamada a getParameter.
Ejercicio 3:
Vamos a ejemplificar más esto con otro ejemplo:
Vamos a crear una nueva página.
 En vista de diseño ingresamos un formulario.
 Creamos tres campos te texto y los etiquetamos como nom, apell y
nctrl.
 En action del formulario ponemos fresp.jsp.
 Creamos otra pagina llamada fresp.jsp.
 En el cuerpo ingresamos el siguiente codigo java embebido:
<p>Holas: <% out.println(request.getParameter("nom")); %></p>
<p>Tus Apellidos son: <% out.println(request.getParameter("Apell"));
%></p>
<p>tu numero de control es: <%
out.println(request.getParameter("nctrl")); %> </p>
Como puedes ver ahí código html combinado con código java la variable
request puede obtener los parámetros enviados por un formulario previamente
de distintas formas como ya habíamos hablado.
Taller Aplicaciones Web con JSP
Dante Mendoza Ruelas
Ejercicio 4:
Ahora vamos a ver un ejemplo un poco mas complicado:
Primero creamos un formulario que tenga varias entradas y minimo una
repetida:
Insertamos dentro de la etiqueta body el siguiente codigo java:
Import java.util.*;
Enumeration paramNames = request.getParameterNames();
while(paramNames.hasMoreElements())
{
String paramName = (String)paramNames.nextElement();
out.println(paramName);
String[] paramValues = request.getParameterValues(paramName);
if (paramValues.length == 1)
{
String paramValue = paramValues[0];
if (paramValue.length() == 0)
out.print("sin valores");
else
out.print(paramValue);
}
else
{
for(int i=0; i<paramValues.length; i++)
{
out.println(paramValues[i]);
}
}
}





Lo que hace primero guarda todos los parámetros en un enumerado.
Luego va de uno en uno y checa si tiene varios valores o ninguno.
Si tiene ninguno muestra sin valor.
Si tiene varios los muestra.
Y así se va con todos los parámetros.
Además de los parámetros también se puede extraer información acerca del
cliente que se conecta, cuando te conectas se le puede pedir información al
navegador y alguna que es obligatoria, como puede ser el agente del
navegador, host, etc.
Una lista de cabeceras de html que se puede extraer del cliente:
Accept Los tipos MIME que prefiere el navegador.
Accept-Charset El conjunto de caracteres que espera el navegador.
Accept-Encoding Los tipos de codificación de datos (como gzip) para que el
navegador sepa como decoficarlos. Los servlets pueden chequear
explícitamente el soporte para gzip y devolver páginas HTML comprimidas con
gzip para navegadores que las soportan, seleccionando la cabecera de
respuesta Content-Encoding para indicar que están comprimidas con gzip. En
Taller Aplicaciones Web con JSP
Dante Mendoza Ruelas
muchos casos, esto puede reducir el tiempo de descarga por un factor de cinco
o diez.
Accept-Language El idioma que está esperando el navegador, en el caso de
que el servidor tenga versiones en más de un idioma.
Authorization Información de autorización, usualmente en respuesta a una
cabecera WWW-Authenticate desde el servidor.
Connection ¿Usamos conexiones persistentes? Sí un servlet obtiene un valor
Keep-Alive aquí, u obtiene una línea de petición indicando HTTP 1.1 (donde las
conexiones persistentes son por defecto), podría ser posible tomar ventaja de
las conexiones persisentes, ahorrando un tiempo significante para las páginas
Web que incluyen muchas piezas pequeñas (imágenes o clases de applets). Para
hacer esto, necesita envíar una cabecera Content-Length en la respuesta, que
es fácimente conseguido escribiendo en un ByteArrayOutputStream, y
preguntando por el tamaño antes de escribir la salida.
Content-Length (para mensajes POST, cúantos datos se han añadido)
Cookie (una de las cabeceras más importantes, puedes ver la sección
independiente de esta tutorial dedicada a los Cookies).
From (dirección email del peticionarios; sólo usado por aceleradores Web, no
por clientes personalizados ni por navegadores).
Host (host y puerto escuchado en la URL original).
If-Modified-Since (sólo devuelve documentos más nuevos que éste, de otra
forma se envía una respuesta 304 "Not Modified" response).
Pragma (el valor no-cache indica que el servidor debería devolver un
documento nuevo, incluso si es un proxy con una copia local).
Referer (la URL de la página que contiene el enlace que el usuario siguió para
obtener la página actual).
User-Agent (tipo de navegador, útil si el servlets está devolviendo contenido
específico para un navegador).
UA-Pixels, UA-Color, UA-OS, UA-CPU (cabeceras no estándard envíadas por
algunas versiones de Internet Explorer, indicando el tamaño de la pantalla, la
profundidad del color, el sistema operativo, y el tipo de CPU usada por el
sistema del navegador).
Para ver todos los detalles sobre las cabeceras HTTP, puedes ver las
especificaciones en http://www.w3.org/Protocols/.
Taller Aplicaciones Web con JSP
Dante Mendoza Ruelas
Ejercicio 5:
Veamos un ejemplo de extracción de cabeceras de html del cliente:
Creamos una nueva pagina
En el cuerpo introducimos el siguiente codigo:
<%@ page import="java.util.*" %>
<%
out.println("Request Method: " + request.getMethod());
out.println("Request URI: " + request.getRequestURI());
out.println("Request Protocol: " + request.getProtocol());
out.println("Lista de Cabezeras: ");
Enumeration headerNames = request.getHeaderNames();
while(headerNames.hasMoreElements())
{
String headerName = (String)headerNames.nextElement();
out.println("<p>" + headerName + "</p>");
out.println("<p>" + request.getHeader(headerName) + "</p>");
}
%>


Lo que hace el codigo es extrae de uno en uno las principales cabeceras
por sus nombres
Luego con un ciclo extrae otras cabeceras
Taller Aplicaciones Web con JSP
Ejercicio 6:
Dante Mendoza Ruelas
Ahora que ya estamos familiarizados realicemos un ejemplo en el que pasemos
parámetros pero a una pagina externa:
Primero crea una pagina
Ahora crea un formulario en el cual pida cadena a buscar, numero de
resultados y que seleccione entre 4 buscadores: Google, Yahoo, Altavista y
Ask.com
El formulario se enviara a otra pagina:
En la otra pagina pegamos este codigo:
<%
String url="";
String searchString = request.getParameter("buscar");
String numResults = request.getParameter("nresultados");
String searchEngine = request.getParameter("Buscador");
if (searchEngine.equals("1"))
url="http://www.google.com/search?q=" + searchString + "&num=" +
numResults;
else if (searchEngine.equals("2"))
url="http://search.yahoo.com/search?_adv_prop=web&va=" +
searchString + "&n=" + numResults;
else if (searchEngine.equals("3"))
url="http://www.altavista.com/web/results?itag=ody&pg=aq&aqmode=s
&aqa=" + searchString + "&nbq=" + numResults;
else if (searchEngine.equals("4"))
url="http://www.ask.com/web?q=" + searchString +
"&qsrc=0&o=0&l=dir";
response.sendRedirect(response.encodeRedirectUrl(url));
%>

Lo que hace, guarda los parametros y compara el parametro del
buscador y dependiendo redirecciona a la pagina del buscador
enviandole los parametros de cadena a buscar y numero de paginas.
Taller Aplicaciones Web con JSP
Dante Mendoza Ruelas
FORMAS DE SEGUIR LA TRAYECTORIA DE LOS USUARIOS (CLIENTES)
Java te permite seguir la trayectoria de un cliente, es decir, obtener y
mantener una determinada información acerca del cliente. De esta forma se
puede tener identificado a un cliente (usuario que está utilizando un browser)
durante un determinado tiempo. Por ejemplo:
 Un claro ejemplo de aplicación de esta técnica es el de los comercios
vía Internet que permiten llevar un carrito de la compra en el que se
van guardando aquellos productos solicitados por el cliente.
 Evitar el nombre de usuario y la password. Muchas grandes sites
requieren registrarse para poder usar sus servicios, pero es un
inconveniente recordar el nombre de usuario y la password. Los cookies
son una buena alternativa para sites de baja seguridad. Cuando un
usuario se registra, se envía una cookie con un único ID de usuario.
Cuando el cliente se reconecta más tarde, se devuelve el ID de usuario,
el servidor los busca, determina que pertenece a un usuario registrado, y
no requiere explícitamente el nombre de usuario y la password.
 Personalizar una Site. Muchos "portales" nos permiten personalizar el
aspecto de la página principal. Usan cookies para recordar lo que
queremos, para que obtengamos el mismo resultado inicial la próxima
vez.
 Publicidad enfocada. Los motores de búsqueda cobran más a sus
clientes por mostrar anuncios "directos" que por anuncios "aleatorios". Es
decir, si hacemos una búsqueda sobre "Java Servlets", un motor de
búsqueda cobra más por un anuncio de un entorno de desarrollo de
Servlets que por el de una agencia de viajes on-line. El problema es que
tienen que enseñarnos un anuncio aleatorio la primera vez que llegamos
y no hemos realizado la búsqueda, así como cuando buscamos algo que
no corresponde con las caegorías de anuncios. Los cookies les permiten
recordar "Oh, esta es la persona que buscó por esto y esto
anteriormente" y muestra un anunció apropiado (lease "caro") en vez de
uno aleatorio (lease "barato").
El mantener información sobre un cliente a lo largo de un proceso que implica
múltiples
conexiones se puede realizar de tres formas distintas:
1. Mediante cookies
2. Mediante seguimiento de sesiones (Session Tracking)
3. Mediante la reescritura de URLs
Taller Aplicaciones Web con JSP
Dante Mendoza Ruelas
Cookies:
 Los cookies son algo que se utiliza para que un servidor HTTP reconozca a un
cliente como alguien que ya se había conectado anteriormente.
 El empleo de cookies requiere que el cliente sea capaz de soportarlas.
 Se requiere que este habilitada la opcion de cookies
 Cada cookie tiene un nombre que puede ser el mismo para varias cookies.
 Se almacenan en un directorio o fichero predeterminado en el disco duro del
cliente.
 Puede mantenerse información acerca del cliente durante días.
 La información guardada no es indefinidamente, pues las cookies tienen una fecha
de caducidad.
 Es posible incluir otros parámetros adicionales, tales como comentarios.
Para enviar una cookie es preciso:
1. Crear un objeto Cookie
2. Establecer sus atributos
3. Enviar la cookie
Por otra parte, para obtener información de una cookie, es necesario:
1. Recoger todas las cookies de la petición del cliente
2. Encontrar la cookie precisa
3. Obtener el valor recogido en la misma
Taller Aplicaciones Web con JSP
Ejercicio 7 Crear un objeto Cookie
Dante Mendoza Ruelas
El constructor de los cookies recibe dos argumentos del tipo string: el identificador y el
valor.
Veamos un ejemplo:
 Crear tres paginas.
 Una con un formulario preguntando dos cosas: color y nombre.
 Otra en la que guarde el cookie.
 Otra en la que lea el cookie.
Cookie1:
Para la pagina uno, simplemente mandar de parámetros el codigo del color que se
selecciona dar como opcion dos colores minimos y que escriba algun dato extra
Cookie2:
Para la cookie2 leer parámetros y guardarlos:
<%
String nombre = request.getParameter("nom");
String color = request.getParameter("color");
Cookie dato1 = new Cookie("nom",nombre);
Cookie dato2 = new Cookie("col",color);
response.addCookie(dato1);
response.addCookie(dato2);
%>
Cookie3:
Para la cookie3 leer cookie y mostrar información al igual que cambiar el fondo de
la pagina por el color seleccionado anteriormente.
<style type="text/css">
<!-body { background-color:
<%
String color= "";
Cookie[] acookies = request.getCookies();
for (int i=0; i< acookies.length; i++)
{
Cookie aux = acookies[i];
if (aux.getName().equals("col"))
color=aux.getValue();
}
out.println(color);
%>;
}
-->
</style>
Taller Aplicaciones Web con JSP
Dante Mendoza Ruelas
Establecer los atributos de la cookie
La clase Cookie proporciona varios métodos para establecer los valores de una cookie y
sus atributos. Entre otros:
Todos estos métodos tienen sus métodos getX() correspondientes incluidos en la misma
clase.
Sessions:
Una sesión es una conexión continuada de un mismo browser a un servidor durante un
tiempo prefijado. Este tiempo depende habitualmente del servidor o se puede establecer
manualmente.
Una sesion es lo mismo que una cookie solamente que la session se encuentra en el lado
del servidor, y trabaja igual que las cookies, se diferencian por identificadores, igual
tienen un limite de tiempo y pueden guardar cualquier tipo de objetos.
La forma de obtener una sesión es mediante el método getSession(boolean) de un objeto
HttpServletRequest. Si este boolean es true, se crea una sesión nueva si es necesario
mientras que si es false, el método devolverá la sesión actual. Por ejemplo:
Taller Aplicaciones Web con JSP
Dante Mendoza Ruelas
Ejercicio :
Vamos a crear una pagina en la cual pidamos datos como nombre,
identificación y alguna clave.
A continuación creamos otra pagina en la cual leeremos esos datos
crearemos una sesion en otra pagina con los datos recogidos.
<%
String nom = request.getParameter("nom");
String ide = request.getParameter("id");
String clave = request.getParameter("clve");
HttpSession misesion = request.getSession(true);
misesion.putValue("nombre",nom);
misesion.putValue("identificador",ide);
misesion.putValue("pass",clave);
%>



Lo que hace es primero lee los datos y los guarda en variables
Luego crea un objeto de tipo sesion
Luego se agrega los datos con algun nombre para identificarlos
Ejercicio :
Ahora vamos a hacer una pagina en la cual lea los datos de la sesion para
verificar que realmente se creo la sesion.
<%
HttpSession misesion = request.getSession(true);
out.println(misesion.getValue("nombre"));
%>
</b>
<p>Tu identificacion es: <b><%
out.println(misesion.getValue("identificador")); %></b></p>
<p>Tu clave es: <b><% out.println(misesion.getValue("pass")); %></b></p>
Taller Aplicaciones Web con JSP
¿Que es lo que se hizo?
 Se creo un objeto del tipo sesion
 Se leyo de uno en uno los valores
Dante Mendoza Ruelas
En la mayoría de los casos, tenemos un nombre atributo específico en
mente, y queremos encontrar el valor (si existe) ya asociado con él. Sin
embargo, también podemos descubrir todos los nombres de atributos en una
sesión dada llamando a getValueNames, que devuelve un array de String o
getAttributeNames, y devuelve una Enumeration.
getId. Este método devuelve un identificador único generado para cada sesión.
Algunas veces es usado como el nombre clave cuando hay un sólo valor
asociado con una sesión, o cuando se uso la información de logging en sesiones
anteriores.
isNew. Esto devuelve true si el cliente (navegador) nunca ha visto la sesión,
normalmente porque acaba de ser creada en vez de empezar una referencia a
un petición de cliente entrante. Devuelve false para sesión preexistentes.
getCreationTime. Devuelve la hora, en milisegundos desde 1970, en la que se
creo la sesión. Para obtener un valor útil para impresión, pasamos el valor al
constructor de Date o al método setTimeInMillis de GregorianCalendar.
getLastAccessedTime. Esto devuelve la hora, en milisegundos desde 1970, en
que la sesión fue enviada por última vez al cliente.
getMaxInactiveInterval. Devuelve la cantidad de tiempo, en segundos, que la
sesión debería seguir sin accesos antes de ser invalidada automáticamente. Un
valor negativo indica que la sesión nunca se debe desactivar.
Ejercicio:
Vamos a probar la lectura de estados de una sesion.
Crearemos una pagina en la cual mostraremos todos los estados de la sesion al
igual que una lista de atributos.
<body>
<p>Hola seas Bienvenido!!!!</p>
<p>que bueno que estas de vuelta.... </p>
<p>Aqui ahi unos datos de tu sesion:</p>
<%@ page import="java.util.*" %>
<% HttpSession misesion = request.getSession(true); %>
<table width="200" border="1">
<tr>
<td>Tipo de Informaci&oacute;n </td>
Taller Aplicaciones Web con JSP
Dante Mendoza Ruelas
<td>Valor</td>
</tr>
<tr>
<td>Identificador:</td>
<td><% out.println(misesion.getId()); %>&nbsp;</td>
</tr>
<tr>
<td>&iquest;Es nueva? </td>
<td><% out.println(misesion.isNew()); %>&nbsp;</td>
</tr>
<tr>
<td>Tiempo de creaci&oacute;n </td>
<td><% out.println(new java.util.Date(misesion.getCreationTime())); %></td>
</tr>
<tr>
<td>Ultimo acceso </td>
<td><%out.println(new java.util.Date(misesion.getLastAccessedTime()));
%></td>
</tr>
<tr>
<td>Intervalo Maximo de Inactividad </td>
<td><% out.println(misesion.getMaxInactiveInterval()); %>&nbsp;</td>
</tr>
</table>
<p>Datos Guardados: </p>
<table width="200" border="1">
<tr>
<td>Nombre</td>
<td>Contenido</td>
</tr>
<%Enumeration lista = misesion.getAttributeNames();
while(lista.hasMoreElements())
{
String valor = (String)lista.nextElement();
out.println("<tr>");
out.println("<td>" + valor + "</td>" +
"<td>" + misesion.getValue(valor) + "</td>" +
"</tr>");
}
%>
</table>
¿Que



es lo que se hace?
Primero se declaran las clases a usar.
Despues se obtiene una sesion.
Se obtiene información de la sesion.


Taller Aplicaciones Web con JSP
Dante Mendoza Ruelas
Se crea un objeto de tipo enumerado con los valores de la sesion.
Se lee de uno en uno.
Variables de Tiempo
Manejo de fechas en java
Los Milisegundos
Trabajar con fechas en java no es algo del otro mundo ni tiene
demasiadas complicaciones, pero la cantidad de formas que hay para hacerlo
puede confundirnos, o peor aún, puede que sólo conozcamos la más mala para
hacerlo.
Las clases java.util.Date y java.sql.Date. Son dos de las clases más
usadas cuando una aplicación implica el trabajo con fechas:
java.util.Date:
 Representa un instante de tiempo específico, con precisión de
milisegundos.
 Antes del jdk1.1 la clase java.util.Date tenía dos funciones.
 Una era la interpretación de datos que tenían que ver con fechas, como
años, días, segundos, entre otros.
 La otra era el formateo (la forma como se muestra) y parseo (convertir
un String a java.util.Date).
 Pero debido a las dificultades que presentaban estas funcionalidades a la
hora de internacionalizar los programas, esos métodos ya está obsoletos
y la clase java.util.Calendar se encargó de esto.
Así que en este momento esta clase, sólo hace lo que se mencionó al principio.
 El año "y" está representado por un entero igual a ("y" - 1900). Por
ejemplo el año 2004 se representa como 104 (2004 - 1900).
 Los meses son representados por números entre 0 y 11, donde enero es 0
y diciembre es 11.
 Los días y minutos se representan de forma corriente. Entre 1 - 31 y 0 59 respectivamente.
 Las horas van entre 0 y 23, donde la medianoche es 0 y el medio día 12.
 Los segundos van entre 0 y 61. 61 solo ocurre cuando se agrega el
segundo adicional para ajustar la diferencia entre el reloj atómico y el
tiempo
de
rotación
de
la
tierra.
Taller Aplicaciones Web con JSP
Dante Mendoza Ruelas
java.sql.Date:
 Esta clase hereda de java.util.Date y es la representación de la fecha
cuando trabajamos con JDBC.
 son los campos almacenados en una base de datos cuyo tipo es una
fecha que puede o no incluir la hora, aunque la clase java.sql.Date
siempre lo hace.
 Al igual que su clase padre, tiene una precisión de milisegundos, con la
excepción que al mostrarla en la salida estándar con el formato por
defecto solo muestra el día, mes y año.
 Hay que anotar también que para campos que almacenen solamente
horas existen otras clases para manejarlos.
En resumen ambas clases, sólo se encargan de almacenar la cantidad de
milisegundos que han pasado desde las 12 de la noche del primero de enero de
1970 en el meridiano de Greenwich.
Aquí vienen dos puntos importantes:
a) Si la fecha que almacena cualquiera de las clases es menor a las 00:00:00
enero 1 de 1970 GMT, su valor el milisegundos será negativo.
b) La fecha es susceptible a la zona horaria. Por ejemplo en Colombia los
milisegundos no se empiezan a contar desde enero 1 de 1970, sino a partir de
las 19:00 de diciembre 31 de 1969.
Ambas clases se pueden instanciar directamente mediante new(), pero la clase
java.sql.Date necesita un parámetro en el constructor: el tiempo en
milisegundos, así que las siguientes instrucciones son válidas:
java.util.Date fechaActual = new java.util.Date(); //Fecha actual del sistema
java.sql.Date inicioLocal = new java.sql.Date(0); //Milisegundo cero
//también se puede crear una instancia de java.util.Date con parámetros
//iniciales
java.util.Date otraFecha = new java.util.Date(1000); //El primer segundo a
partir del inicio
Taller Aplicaciones Web con JSP
Dante Mendoza Ruelas
Se puede pasar de java.sql.Date a java.util.Date de dos formas, una de ellas es
con una asignación simple:
java.util.Date utilDate = null;
java.sql.Date sqlDate = new java.sql.Date(0);
utilDate = sqlDate;
/* aunque es java.util.Date,
si la imprimes tendrá el formato de java.sql.Date, recordemos que
java.sql.Date hereda de
java.util.Date */
System.out.println(utilDate);
También se pueden tomar los milisegundos de java.sql.Date y pasarlos al
constructor de java.util.Date:
java.util.Date utilDate = null;
java.sql.Date sqlDate = new java.sql.Date(0);
utilDate = new java.util.Date(sqlDate.getTime());
//esta vez se mostrará con el formato de java.util.Date
System.out.println(utilDate);
Para pasar de java.util.Date a java.sql.Date se deben tomar los milisegundos
de la primera y pasarlos al constructor de la segunda:
java.util.Date utilDate = new java.util.Date();
java.sql.Date sqlDate = new java.sql.Date(utilDate.getTime());
//Con formato de java.sql.Date
System.out.println(sqlDate);
Para comparar fechas usamos el método compareTo() que internamente
compara los milisegundos entre ellas usando directamente los métodos
getTime() de ambas clases.
java.util.Date utilDate = new java.util.Date();
java.sql.Date sqlDate = new java.sql.Date(utilDate.getTime());
if (utilDate.compareTo(sqlDate) == 0){
System.out.println("IGUALES");
}else{
System.out.println("DIFERENTES");
}
Taller Aplicaciones Web con JSP
O lo que es equivalente:
Dante Mendoza Ruelas
java.util.Date utilDate = new java.util.Date();
java.sql.Date sqlDate = new java.sql.Date(utilDate.getTime());
if (utilDate.getTime() == sqlDate.getTime()){
System.out.println("IGUALES");
}else{
System.out.println("DIFERENTES");
}
 Las clases Time y Timestamp
Al igual que java.sql.Date, son hijas (heredan) de java.util.Date, es
decir, su núcleo son los milisegundos.
La clase Time es un envoltorio de la clase java.util.Date para
representar los datos que consisten de horas, minutos, segundos y
milisegundos,
 mientras Timestamp representa estos mísmos datos más un atributo con
nanosegundos, de acuerdo a las especificaciones del lenguaje SQL para
campos de tipo TIMESTAMP.
Como ambas clases heredan del java.util.Date, es muy fácil pasar de un
tipo de dato a otro;
 tanto Time como Timestamp se pueden instanciar directamente
 y su constructor tiene como parámetro el número de milisegundos;
 La clase Time sólamente muestra la hora, minutos y segundo, mientras
timestamp agrega fracciones de segundo a la cadena.
 Para convertir entre tipos de datos diferentes debemos usar los
milisegundos de una clase y asignarlos a las instancias de las otras.
 Note que aún cuando todos los objetos tienen los mismos milisegundos el
formato con el que se muestran dependen de la clase que realmente los
contiene.
 Si creamos nuevas instancias con los milisegundos los formatos con que
se muestran son los mismos.
Formateo de Fechas:
Para formatear fechas existen infinidad de formas pero una de las mas
sencillas es con la clase SimpleDateFormat :
SimpleDateFormat miformato = new SimpleDateFormat("dd/MM/yy");
out.println(miformato.format(utilfecha));
Taller Aplicaciones Web con JSP
Dante Mendoza Ruelas
Ejercicio:
Vamos a englobar todo lo de tiempo en un solo ejercicio:
<p>La fecha actual es:<%
java.util.Date fechaActual = new java.util.Date(); //Fecha actual del sistema
java.sql.Date inicioLocal = new java.sql.Date(0); //Milisegundo cero
//también se puede crear una instancia de java.util.Date con parámetros
iniciales
java.util.Date otraFecha = new java.util.Date(1000); //El primer segundo a
partir del inicio
out.println(fechaActual);
%></p>
<p>La fecha inicial de SqlDate: <% out.println(inicioLocal);%></p>
<p>La fecha inicial mas 1000 segundos: <% out.println(otraFecha);%></p>
<p>Comparacion de dos fechas:<%
java.util.Date utilfecha = new java.util.Date();
java.sql.Date sqlfecha = new java.sql.Date(utilfecha.getTime());
if (utilfecha.compareTo(sqlfecha) == 0){
out.println("IGUALES");
}else{
out.println("DIFERENTES");
}
utilfecha = new java.util.Date(); //fecha actual
long lnMilisegundos = utilfecha.getTime();
sqlfecha = new java.sql.Date(lnMilisegundos);
java.sql.Time sqltiempo = new java.sql.Time(lnMilisegundos);
java.sql.Timestamp sqlTimestamp = new java.sql.Timestamp(lnMilisegundos);
out.println("<p>util.Date: "+utilfecha + "</p>");
out.println("<p>sql.Date: "+sqlfecha + "</p>");
out.println("<p>sql.Time: "+sqltiempo + "</p>");
out.println("<p>sql.Timestamp: "+sqlTimestamp + "</p>");
utilfecha = sqltiempo;
out.println("<p>util.Date apuntando a sql.Time: ["+sqltiempo+"]" + "</p>");
utilfecha = sqlTimestamp;
out.println("util.Date apuntando a sql.Timestamp: ["+sqlTimestamp+"]" +
"</p>");
utilfecha = new java.util.Date(sqltiempo.getTime());
out.println("<p>util.Date con milisegundos de sql.Time: ["+utilfecha+"]</p>");
utilfecha = new java.util.Date(sqlTimestamp.getTime());
out.println("<p>util.Date
con
milisegundos
de
sql.Timestamp:
["+utilfecha+"]</p>");
SimpleDateFormat miformato = new SimpleDateFormat("dd/MM/yy");
out.println(miformato.format(utilfecha));
%>
Taller Aplicaciones Web con JSP
Dante Mendoza Ruelas
JDBC:
La API JBDC es una interfaz de acceso a RDBMS(Relational Database
Management System) independiente de la plataforma y del gestor de bases de
datos utilizado.Se relaciona muy a menudo con el acronimo ODBC por lo que se
suele expresar como Java Database Connectivity pero oficialmente,según
javasoft,JDBC no significa nada ni es acronimo de nada.
El API consiste en una serie de interfaces Java implementadas por un
controlador.Este programa de gestión se encarga de la traducción a las
llamadas estandar que requiere la base de datos compatible con el.De esta
manera el programador puede abstraerse de la programación especifica de la
base de datos creando codigo que funcionará para todas los RDBMS que cuenten
con un driver JDBC con solo cambiar tal driver.
En la actualidad se encuentran drivers JDBC para todos los sistemas de
gestión de bases de datos mas populares(e incluso podriamos decir existentes)
como Informix,Oracle,SQLServer, DB2,InterBase, SyBase... y otros productos de
indole no comercial como mSql,mySql y PostGress,etc,.
Aun asi existe un tipo especial de drivers denominados puentes JDBCODBC que traducen las llamadas en JDBC a llamadas en el estandar de
comunicación con bases de datos desarrollado por Microsoft ODBC por lo que en
ultimo termino siempre se podrá utilizar uno de estos drivers ya que la
totalidad de los sistemas de gestión de bases de datos cuentan con un driver de
este ultimo tipo.Esto nos lleva a la clasificación de los distintos drivers que
cumplen la especificación JDBC.
Tipos de drivers JDBC
A continuación se señalan y describen los cuatro tipos distintos de drivers JDBC
existentes:
 Nivel 1: Puente JDBC:ODBC.
Esta categoría de controladores se remite al controlador de puente
JDBC-ODBC original. Este ultimo utiliza el controlador ODBC de Microsoft
para comunicarse con los servidores de base de datos.Se implementa
tanto en codigo binario como en Java y debe ser instalado previamente
en la computadora cliente antes de poder usarlo.
 Nivel 2: Controlador JDBC de protocolo nativo en Java y binario.
Esta categoría esta compuesta por controladores que hablan con los
servidores de bases de datos en el protocolo nativo de la base de
datos.Se implementan como una combinación de codigo binario y Java y
deben ser instalados en el cliente antes de poder ser usados.
Nivel 3:Controlador JDBC de protocolo no nativo en Java puro.
Esta categoría esta formada por controladores de Java puro( no hay
codigo binario) que hablan un protocolo de red estandar(como http) con
un servidor de acceso a bases de datos.Este servidor traduce el
protocolo de red a uno de base de datos específicos de la marca.No
necesita instalación en cliente.
Taller Aplicaciones Web con JSP

Dante Mendoza Ruelas
Nivel 4: Controlador JDBC de protocolo nativo en Java puro
Está formada por controladores de Java puro que hablan el protocolo de
la base de datos específico de la marca del servidor de bases de datos
que se haya designado para servir de interfaz. No necesita instalación en
cliente.
Como se observa la clasificación de los niveles de controladores JDBC se hace
en función de que hablen el protocolo nativo de la base de datos y de que se
encuentren implementados en Java puro o parcialmente estén escritos en
código binario dependiente de la plataforma. Con respecto a lo primero la
eliminación de las capas de traducción en el caso de que la llamada del driver
no sea nativa pueden degradar el rendimiento pero hay ocasiones en que no
hay otra opción. Por otra parte el hecho de que el driver esté escrito en Java
puro consigue, aparte de independencia de la plataforma de ejecución, que no
sea necesaria instalación ni configuración(como el caso del DSN del ODBC) en el
cliente lo que facilita la gestión y siendo la única solución en casos en que el
cliente sea un applet. Si encontramos los 4 niveles de drivers el más adecuado
en el 95% de las ocasiones será el de nivel 4.
Configuración del Driver:
En nuestros ejemplos usaremos un driver del tipo fuente, debido a la
comodidad, de cierta forma “generico” y que todos si no es que la mayoria
tenemos ODBC.



Primero daremos de alta el ODBC de nuestra base de datos, en este caso
SQL.
Ahí que tener mucho cuidado en seleccionar un ODBC de tipo System
DSN y no USER.
Una vez dado de alta para configurar el driver no tenemos que hacer
nada ya viene incluido en el servidor y solo basta con mandarlo a hablar.
Establecer una Conexión
Lo primero que tenemos que hacer es establecer una conexión con el
controlador de base de datos que queremos utilizar. Esto implica dos pasos: (1)
cargar el driver y (2) hacer la conexión.
Taller Aplicaciones Web con JSP
Cargar los Drivers
Dante Mendoza Ruelas
Cargar el driver o drivers que queremos utilizar es muy sencillo y sólo implica
una línea de código. En nuestro caso por ejemplo, queremos utilizar el puente
JDBC-ODBC, se cargaría la siguiente línea de código.
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
La documentación del driver nos dará el nombre de la clase a utilizar. Por
ejemplo, si el nombre de la clase es jdbc.DriverXYZ, cargaríamos el driver con
esta línea de código.
Class.forName("jdbc.DriverXYZ");
No necesitamos crear un ejemplar de un driver y registrarlo con el
DriverManager porque la llamada a Class.forName lo hace automáticamente.
Si hubiéramos creado nuestro propio ejemplar, creariamos un duplicado
innecesario, pero no pasaría nada.
Una vez cargado el driver, es posible hacer una conexión con un controlador de
base de datos.
Hacer la Conexión
El segundo paso para establecer una conexión es tener el driver apropiado
conectado al controlador de base de datos. La siguiente línea de código ilustra
la idea general.
Connection con = DriverManager.getConnection(url, "myLogin",
"myPassword");
Este paso también es sencillo, lo “difícil” es saber qué suministrar para url. Si
estamos utilizando el puente JDBC-ODBC, el JDBC URL empezará con
jdbc:odbc:. el resto de la URL normalmente es la fuente de nuestros datos o el
sistema de base de datos. Por eso, si estamos utilizando ODBC para acceder a
una fuente de datos ODBC llamada "Dante," por ejemplo, nuestro URL podría
ser jdbc:odbc:Dante. En lugar de "myLogin" pondríamos el nombre utilizado
para entrar en el controlador de la base de datos; en lugar de "myPassword"
pondríamos nuestra password para el controlador de la base de datos. Por eso
si entramos en el controlador con el nombre "DaN" y la password de "fuga" estas
dos líneas de código estableceran una conexión.
String url = "jdbc:odbc:Dante";
Connection con = DriverManager.getConnection(url, "DaN", "fuga");
Si estamos utilizando un puente JDBC desarrollado por una tercera parte, la
documentación nos dirá el subprotocolo a utilizar, es decir, qué poner despues
Taller Aplicaciones Web con JSP
Dante Mendoza Ruelas
de jdbc: en la URL. Por ejemplo, si el desarrollador ha registrado el nombre
"acme" como el subprotocolo, la primera y segunda parte de la URL de JDBC
serán jdbc:acme:. La documentación del driver también nos dará las guías para
el resto de la URL del JDBC. Esta última parte de la URL suministra información
para la identificación de los datos fuente.
Si uno de los drivers que hemos cargado reconoce la URL suministada por el
método DriverManager.getConnection, dicho driver establecerá una conexión
con el controlador de base de datos especificado en la URL del JDBC. La clase
DriverManager, como su nombre indica, maneja todos los detalles del
establecimiento de la conexión detrás de la escena. A menos que estemos
escribiendo un driver, posiblemente nunca utilizaremos ningún método del
interface Driver, y el único método de DriverManager que realmente
necesitaremos conocer es DriverManager.getConnection.
La conexión devuelta por el método DriverManager.getConnection es una
conexión abierta que se puede utilizar para crear sentencias JDBC que pasen
nuestras sentencias SQL al controlador de la base de datos. En el ejemplo
anterior, con es una conexión abierta, y se utilizará en los ejemplos
posteriores.
Seleccionar una Tabla
Primero, crearemos una de las tablas de nuestro ejemplo. Esta tabla,
ALUMNOS, contiene la información esencial sobre los alumnos inscritos en el
taller de java "Aplicaciones Orientadas a Web con JSP", incluyendo los
nombres, sus apellidos, sus numeros de control, su semestre en el que cursan y
el sexo. Aquí puedes ver la tabla ALUMNOS, que describiremos más adelante.
alum_nom Sex apell no_ctrl c_id
Laura
F
xx
03130307 1
Esperanza F
8.99 324
2
Vicky
F
9.99 0435
03
Lala
M
8.99 0435
4
Fuga Fuga 49 9.99 0546
5
La columna que almacena el nombre del alumno es alum_nom, y contiene
valores con el tipo VARCHAR de SQL y una longitud máxima de 15 caracteres.
La segunda columna, llamada sex, contiene un carácter indicando el sexo de la
persona; este carácter será un tipo CHAR de SQL. La tercera columna, llamada
apell, almacena valores del tipo VARCHAR de longitud de 30. La columna
llamada noctrl almacena valores del tipo INTEGER de SQL e indica el número
Taller Aplicaciones Web con JSP
Dante Mendoza Ruelas
de control del alumno; El número de control servirá de clave primaria.. La
columna final, c_id, contiene obviamente la carrera de tipo INTEGER de SQL.
MATERIAS, la segunda tabla de nuestra base de datos, tiene información sobre
cada materia.
mat_id
Mat_nom
mat_sem c_id m_cred
A100
Base de Datos II 3
1
10
A101
Programación III 4
2
10
A102
Simulación
3
10
5
La siguiente sentencia SQL crea la tabla ALUMNOS.
CREATE TABLE ALUMNOS
(alum_nom VARCHAR(15),
sex CHAR(1),
apell VARCHAR(30),
no_ctrl INT,
c_id INT)
Este código no termina con un terminador de sentencia de un controlador de
base de datos, que puede variar de un controlador a otro. Por ejemplo, Oracle
utiliza un punto y coma (;) para finalizar una sentencia, y Sybase utiliza la
plabra go. El driver que estamos utilizado proporcionará automáticamente el
terminador de sentencia apropiado, y no necesitaremos introducirlo en nuestro
código JDBC.
Otra cosa que debíamos apuntar sobre las sentencias SQL es su forma. En la
sentencia CREATE TABLE, las palabras clave se han imprimido en letras
máyusculas, y cada ítem en una línea separada. SQL no requiere nada de esto,
estas convenciones son sólo para una fácil lectura. El estándard SQL dice que la
palabras claves no son sensibles a las mayúsculas, así, por ejemplo, la anterior
sentencia SELECT pude escribirse de varias formas.
Taller Aplicaciones Web con JSP
Dante Mendoza Ruelas
Hasta ahora hemos escrito la sentencia SQL que crea la tabla ALUMNOS. Ahora
le pondremos comillas (crearemos un string) y asignaremos el string a la
variable createTableAlumnos. Como hemos visto, al controlador de base de
datos no le importa si las líneas están divididas, pero en el lenguaje Java, un
objeto String que se extienda más allá de una línea no será compilado.
Consecuentemente, cuando estamos entregando cadenas, necesitamos encerrar
cada línea entre comillas y utilizar el signo más (+) para concatenarlas.
String createTableAlumnos = "CREATE TABLE ALUMNOS " +
"( alum_nom VARCHAR(15),sex CHAR(1),apell VARCHAR(30),” +
“no_ctrl INT, c_id INT )";
Crear sentencias JDBC
Un objeto Statement es el que envía nuestras sentencias SQL al controlador de
la base de datos. Simplemente creamos un objeto Statement y lo ejecutamos,
suministando el método SQL apropiado con la sentencia SQL que queremos
enviar. Para una sentencia SELECT, el método a ejecutar es executeQuery.
Para sentencias que crean o modifican tablas, el método a utilizar es
executeUpdate.
Se toma un ejemplar de una conexión activa para crear un objeto Statement.
En el siguiente ejemplo, utilizamos nuestro objeto Connection: con para crear
el objeto Statement: stmt.
Statement stmt = con.createStatement();
En este momento stmt existe, pero no tiene ninguna sentencia SQL que pasarle
al controlador de la base de datos. Necesitamos suministrarle el metodo que
utilizaremos para ejecutar stmt. Por ejemplo, en el siguiente fragmento de
código, suministramos executeUpdate con la sentencia SQL del ejemplo
anterior.
stmt.executeUpdate("CREATE TABLE ALUMNOS " +
"( alum_nom VARCHAR(15),sex CHAR(1),apell VARCHAR(30),” +
“no_ctrl INT, c_id INT )";
Al igual podemos crear un String y pasarlo como parametro.
String insert = “stmt.executeUpdate(createTableAlumnos);
Taller Aplicaciones Web con JSP
Dante Mendoza Ruelas
Ejecutar Sentencias
Utilizamos el método executeUpdate porque la sentencia SQL contenida en
createTableAlumnos es una sentencia DDL (data definition language). Las
sentencias que crean, modifican o eliminan tablas son todas ejemplos de
sentencias DDL y se ejecutan con el método executeUpdate. Cómo se podría
esperar de su nombre, el método executeUpdate también se utiliza para
ejecutar sentencias SQL que actualizan un tabla.
El método más utilizado para ejecutar sentencias SQL es executeQuery. Este
método se utiliza para ejecutar sentencias SELECT, que comprenden la amplia
mayoría de las sentencias SQL.
Ejercicio:
Vamos a crear una nueva tabla en la base de datos pubs
Creamos una pagina nueva con un formulario preguntando el nombre de la base
de la tabla.
En otra pagina leemos el parámetro y creamos la tabla.
<%
String usuario = request.getParameter("user");
String clave = request.getParameter("pass");
String nom = request.getParameter("nombre");
String url = "jdbc:odbc:dbtaller";
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection con = DriverManager.getConnection(url, usuario, clave);
String createTableAlumnos = "CREATE TABLE ALUMNOS " +
"(alum_nom VARCHAR(15),sex CHAR(1),apell VARCHAR(30)," +
"no_ctrl INT, c_id INT )";
Statement stmt = con.createStatement();
stmt.executeUpdate(createTableAlumnos);
%>
Felicidades tu tabla ha sido creada!!!
¿Que se esta haciendo?
Pues lo mismo que se había explicado anteriormente
Taller Aplicaciones Web con JSP
Dante Mendoza Ruelas
Introducir Datos en una Tabla
Ahora introduciremos datos en nuestra tabla una fila cada vez, suministrando la
información a almacenar en cada columna de la fila.
Statement stmt = con.createStatement();
stmt.executeUpdate(
"INSERT INTO ALUMNOS " +
"VALUES ('Dante', 'm', 'Mendoza Ruelas', '03130307', '1')");
El siguiente código inserta una segunda línea dentro de la tabla COFFEES. Observa que
hemos reutilizado el objeto Statement: stmt en vez de tener que crear uno nuevo para
cada ejecución.
Ejercicio :
Vamos a insertar a nuestra tabla datos de la siguiente manera:
Cremamos una pagina en la cual reciba los datos y otra en que los guarde en la base de
datos.
Asi se veria la segunda:
<%
String d1 = request.getParameter("nom");
String d2 = request.getParameter("apell");
String d3 = request.getParameter("sexo");
String d4 = request.getParameter("ncontrol");
String d5 = request.getParameter("carrera");
String usuario = "DaN";
String clave = "perfidia";
String url = "jdbc:odbc:dbtaller";
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection con = DriverManager.getConnection(url, usuario, clave);
Statement stmt = con.createStatement();
stmt.executeUpdate("insert into ALUMNOS values ('" + d1 + "','" + d3 + "','" +
d2 + "','" + d4 + "','" + d5 + "')");
%>
<p>Se han insertado los siguientes datos: </p>
<p>Nombre: <% out.println(d1); %></p>
<p>Apellidos: <% out.println(d2); %></p>
<p>Sexo: <% out.println(d3); %></p>
<p>Numero de control: <% out.println(d4); %></p>
<p>Carrera: <% out.println(d5); %></p>
Taller Aplicaciones Web con JSP
Obtener Datos desde una Tabla
Dante Mendoza Ruelas
JDBC devuelve los resultados en un objeto ResultSet, por eso necesitamos declarar un
ejemplar de la clase ResultSet para contener los resultados. El siguiente código presenta
el objeto ResultSet: rs y le asigna el resultado de una consulta anterior.
ResultSet rs = stmt.executeQuery("SELECT alum_nom, apell FROM
ALUMNOS");
Utilizar el Método next
La variable rs, que es un ejemplar de ResultSet, contiene las filas de alumnos y sus
apellidos mostrados en el juego de resultados de la página anterior. Para acceder a los
nombres y apellidos, iremos a la fila y recuperaremos los valores de acuerdo con sus
tipos. El método next mueve el cursor a la siguiente fila y hace que esa fila (llamada fila
actual) sea con la que podamos operar. Como el cursor inicialmente se posiciona justo
encima de la primera fila de un objeto ResultSet, primero debemos llamar al método
next para mover el cursor a la primera fila y convertirla en la fila actual. Sucesivas
invocaciones del método next moverán el cursor de línea en línea de arriba a abajo.
Utilizar los métodos getXXX
Los métodos getXXX del tipo apropiado se utilizan para recuperar el valor de cada
columna. Por ejemplo, la primera columna de cada fila de rs es ALUM_NOM, que
almacena un valor del tipo VARCHAR de SQL. El método para recuperar un valor
VARCHAR es getString.
JDBC ofrece dos formas para identificar la columna de la que un método
getXXX obtiene un valor. Una forma es dar el nombre de la columna, como se
ha hecho arriba. La segunda forma es dar el índice de la columna (el número de
columna), con un 1 significando la primera columna, un 2 para la segunda, etc.
Métodos para Recuperar Tipos SQL muestra qué métodos pueden utilizarse
legalmente para recuperar tipos SQL, y más importante, qué métodos están
recomendados para recuperar los distintos tipos SQL. Observa que esta tabla
utiliza el término "JDBC type" en lugar de "SQL type." Ambos términos se
refieren a los tipos genéricos de SQL definidos en java.sql.Types, y ambos son
intercambiables.
Taller Aplicaciones Web con JSP
Dante Mendoza Ruelas
Utilizar los métodos de ResultSet.getXXX para Recuperar tipos JDBC
Taller Aplicaciones Web con JSP
Dante Mendoza Ruelas
Una "x" indica que el método getXXX se puede utilizar legalmente para recuperar el tipo
JDBC dado.
Una "X" indica que el método getXXX está recomendado para recuperar el tipo JDBC
dado.
Ejercicio:
Vamos a hacer una consulta de la base de datos:
<p>Se han leido los siguientes datos: </p>
<%
String usuario = "DaN";
String clave = "perfidia";
String url = "jdbc:odbc:dbtaller";
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection con = DriverManager.getConnection(url, usuario, clave);
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("select * from ALUMNOS");
while (rs.next()) {
String d1 = rs.getString("alum_nom");
String d3 = rs.getString("sex");
String d2 = rs.getString("apell");
String d4 = rs.getString("no_ctrl");
String d5 = rs.getString("c_id");
out.println("<p>Nombre: " + d1 + "</p>");
out.println("<p>Apellidos: " + d2 + "</p>");
out.println("<p>Sexo: " + d3 + "</p>");
out.println("<p>Numero de control: " + d4 + "</p>");
out.println("<p>Carrera: " + d5 + "</p>");
}
%>
Taller Aplicaciones Web con JSP
Utilizar Sentencias Preparadas
Dante Mendoza Ruelas
Algunas veces es más conveniente o eficiente utilizar objetos
PreparedStatement para enviar sentencias SQL a la base de datos. Este tipo
especial de sentencias se deriva de una clase más general, Statement, que ya
conocemos.
Cuándo utilizar un Objeto PreparedStatement
Si queremos ejecutar muchas veces un objeto Statement, reduciremos el
tiempo de ejecución si utilizamos un objeto PreparedStatement, en su lugar.
La característica principal de un objeto PreparedStatement es que, al
contrario que un objeto Statement, se le entrega una sentencia SQL cuando se
crea. La ventaja de esto es que en la mayoría de los casos, esta sentencia SQL
se enviará al controlador de la base de datos inmediatamente, donde será
compilado. Como resultado, el objeto PreparedStatement no sólo contiene
una sentencia SQL, sino una sentencia SQL que ha sido precompilada. Esto
significa que cuando se ejecuta la PreparedStatement, el controlador de base
de datos puede ejecutarla sin tener que compilarla primero.
Aunque los objetos PreparedStatement se pueden utilizar con sentencias SQL
sin parámetros, probablemente nosotros utilizaremos más frecuentemente
sentencias con parámetros. La ventaja de utilizar sentencias SQL que utilizan
parámetros es que podemos utilizar la misma sentencia y suministrar distintos
valores cada vez que la ejecutemos.
Crear un Objeto PreparedStatement
Al igual que los objetos Statement, creamos un objeto PreparedStatement con
un objeto Connection. Utilizando nuestra conexión con abierta en ejemplos
anteriores, podríamos escribir lo siguiente para crear un objeto
PreparedStatement que tome dos parámetros de entrada.
PreparedStatement actualizar = con.prepareStatement(
"UPDATE ALUMNOS SET c_id = ? WHERE no_ctrl LIKE ?");
Suministrar Valores para los Parámetros de un PreparedStatement
Necesitamos suministrar los valores que se utilizarán en los lugares donde están
las marcas de interrogación, si hay alguno, antes de ejecutar un objeto
PreparedStatement. Podemos hacer esto llamado a uno de los métodos setXXX
definidos en la clase PreparedStatement. Si el valor que queremos sustituir
por una marca de interrogación es un int de Java, podemos llamar al método
setInt. Si el valor que queremos sustituir es un String de Java, podemos llamar
Taller Aplicaciones Web con JSP
Dante Mendoza Ruelas
al método setString, etc. En general, hay un método setXXX para cada tipo
Java.
Utilizando el objeto actualizar del ejemplo anterior, la siguiente línea de
código selecciona la primera marca de interrogación para un int de Java, con
un valor de 5.
actualizar.setInt(1, 5);
Cómo podríamos asumir a partir de este ejemplo, el primer argumento de un
método setXXX indica la marca de interrogación que queremos seleccionar, y
el segundo argumento el valor que queremos ponerle. El siguiente ejemplo
selecciona la segunda marca de interrogación con el int "03130307".
updateSales.setInt(2, 03130307);
Valores de retorno del método executeUpdate
Siempre que executeQuery devuelve un objeto ResultSet que contiene los
resultados de una petición al controlador de la base datos, el valor devuelto
por executeUpdate es un int que indica cuántas líneas de la tabla fueron
actualizadas. Si realizo una creación de una tabla devuelve un 0 o si realizo una
consulta un numero dependiendo de los resultados encontrados.
Ejercicio:
Hagamos una pagina en la cual actualizemos datos de la tabla ALUMNOS usando
una sentencia previamente preparada.
<%
String usuario = "DaN";
String clave = "perfidia";
String url = "jdbc:odbc:dbtaller";
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection con = DriverManager.getConnection(url, usuario, clave);
PreparedStatement actualizar = con.prepareStatement("UPDATE
ALUMNOS SET c_id = ? WHERE no_ctrl = ?");
actualizar.setInt(1, 5);
actualizar.setInt(2, 3130307);
actualizar.executeUpdate();
%>
Taller Aplicaciones Web con JSP
Dante Mendoza Ruelas
Procedimientos almacenados del lado del servidor
Hagamos un procedimiento almacenado en el sql y ejecutemoslo en una pagina
<%
String usuario = "DaN";
String clave = "perfidia";
String url = "jdbc:odbc:dbtaller";
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection con = DriverManager.getConnection(url, usuario, clave);
CallableStatement cs = con.prepareCall("exec taller 3130307");
cs.execute();
%>
Taller Aplicaciones Web con JSP
Dante Mendoza Ruelas
ENVIO DE EMAILS
Introducción al API JavaMail
El API JavaMail es un paquete opcional (extensión estándard) para leer, componer, y
enviar mensajes electrónicos.
Usamos este paquete para crear programas del tipo MUA (Mail User Agent), similares a
Eudora, Pine, y Microsoft Outlook. Su propósito principal no es transportar, enviar, o reenviar mensajes como sendmail u otros programas del tipo MTA (Mail Transfer Agent).
En otras palabras, los usuarios interactúan con los programas para leer y escribir e-mails.
Los programas MUA tratan con los programas MTA para el envío real.
El API JavaMail está diseñado para proporcionar acceso independiente del protocolo para
enviar y recibir mensajes dividiendose en dos partes:
La primera parte del API básicamente es, cómo enviar y recibir mensajes
independientemente del proveedor/protocolo.
La segunda parte habla de lenguajes especificos del protocolo como SMTP, POP, IMAP,
y NNTP. Con el API, JavaMail para poder comunicar con un servidor, necesitamos un
proveedor para un protocolo.
Revisión de los Protocolos Relacionados
Antes de mirar dentro de las especificaciones del API JavaMail, echemos un vistazo a los
protocolos usados con el API. Básicamente son cuatro:
SMTP
POP
IMAP
MIME
SMTP
El protocolo Simple Mail Transfer Protocol (SMTP) está definido por la RFC 821.
Define el mecanismo para enviar e-mail. En el contexto del API JavaMail, nuestro
programa basado en JavaMail comunicará con el servidor SMTP de nuestro proveedor de
servicios (ISP). Este servidor SMTP dejará el mensaje en el servidor SMTP del
recipiente(s) para que sea recogido por los usuarios a través de POP o IMAP. Esto no
requiere que nuestro servidor SMTP sea vulnerable, pues se utiliza la autentificación,
pero es nuestra responsabilidad asegurarnos de que el servidor SMTP se configure
correctamente. No hay nada en el API JavaMail sobre tareas como el configuración de un
servidor para retransmitir mensajes o para agregar y para quitar cuentas del e-mail.
POP
POP viene de Post Office Protocol. Actualmante en la versión 3, también conocido
como POP3, la RFC 1939 define este protocolo.
POP es el mecanismo que la mayoría de la gente usa en Internet para conseguir su correo.
Define el soporte de un sólo mailbox por cada usuario. Ésto es todo lo que lo hace, y ésta
también es la fuente de la mayoría de la confusión. Muchas de las cosas con que gente se
familiariza cuando usa POP, como la capacidad de ver cuántos mensajes de correo
nuevos tienen, no lo soporta POP en absoluto. Estas capacidades se construyen en
programas como Eudora o Microsoft Outlook, que recuerdan cosas como los últimos
correos recibidos y calculan cuántos tenemos nuevos. Así pues, al usar el API JavaMail,
si queremos este tipo de información tendremos que calcularla nosotros mismos.
Taller Aplicaciones Web con JSP
Dante Mendoza Ruelas
IMAP
IMAP es un protocolo más avanzado para recibir mensajes. Definido en la RFC 2060,
IMAP viene de Internet Message Access Protocol, y está actualmente en la versión 4,
también conocida como IMAP4. Para usar el IMAP, nuestro servidor de correo debe
soportar este protocolo. No podemos simplemente cambiar nuestro programa para usar
IMAP en vez de POP y que se soporte todo IMAP. Si asumimos que nuestro servidor de
correo soporta IMAP, nuestro programa basado en JavaMail puede aprovecharse de los
usuario que tienen carpetas múltiples en el servidor y estas carpetas se pueden compartir
por varios usuarios.
Debido a las capacidades más avanzadas, podríamos pensar que IMAP sería utilizado por
todos. Pero no es así. Sobrecarga mucho el servidor de correo, requiriendo que el servidor
reciba los nuevos mensajes, los entrege a los usuarios cuando sean solicitados, y los
mantiene en las distintas carpetas de cada usuario. Aunque que esto centraliza las copias
de seguridad, también hace que las carpetas de correo a largo plazo de los usuarios se
hagan cada vez más grandes, y todo el mundo sufre cuando se agota el espacio en el
disco. Con POP, los mensajes recuperados son eliminados del servidor de correo.
MIME
MIME viene de Multipurpose Internet Mail Extensions. No es un protocolo de
transferencia de e-mail. En su lugar, define el contenido de lo que se está transfiriendo: el
formato de los mensajes, los attachments, etc. Hay muchos documentos que tienen efecto
sobre esto: las RFC 822, RFC 2045, RFC 2046, y RFC 2047. Como usuario del API
JavaMail, normalmente no tendremos que preocuparnos sobre estos formatos. Sin
embargo, estos formatos existen y son utilizados por nuestros programas.
Las clases Corazón
Revisar las Clases Corazón
Antes de profundizar en las classes de JavaMail, veremos las clases corazón que
componen el API: Session, Message, Address, Authenticator, Transport, Store, y
Folder. Todas estas clases se encuentran en el paquete del nivel superior del
API JavaMail: javax.mail, aunque frecuentemente nos veremos utilizando clases
del paquete javax.mail.internet.
Session
La clase Session define una sesión de correo básica. Es a través de esta de
sesión de la que todas las demás funcionan. El objeto Session se aprovecha de
un objeto java.util.Properties para obtener información como el servidor de
correo, el nombre de usuario, la password, y otra información que puede
compartirse a lo largo de toda la aplicación.
El constructor para las clases es privado. Podemos obtener una sola sesión por
defecto que puede ser compartida con el método getDefaultInstance():
Taller Aplicaciones Web con JSP
Message
Dante Mendoza Ruelas
Una vez que tenemos nuestro objeto Session, es hora de empezar a crear un
mensaje para enviar. Esto se hace con un objeto Message.
Siendo una clase abstracta, debemos trabajar con una subcalse, en la mayoría
de los casos será javax.mail.internet.MimeMessage.
Un MimeMessage es un mensaje de e-mail que entiende los tipos MIME,
definidos en las distintas RFCs.
Para crear un Message, le pasamos el objeto Session al constructor de
MimeMessage:
MimeMessage message = new MimeMessage(session);
El mecanismo básico para configurar el contenidos es el método setContent(),
con los argumentos para el contenido y tipo mime:
message.setContent("Hello", "text/plain");
Sin embargo, si sabemos que estámos trabajando con un MimeMessage y
nuestro mensaje es texto plano, podemos usar su método setText() que sólo
requiere el contenido real, dejando por defecto el tipo MIME a text/plain:
message.setText("Hello");
Para seleccionar el subject, usamos el método setSubject():
message.setSubject("First");
Address
Una vez que hemos creado la Session y el Message, y también hemos rellenado
el mensaje con contenido, es hora de poner dirección a nuestra carta con un
objeto Address.
Para crear una dirección con sólo la dirección e-mail, se la pasamos al
constructor:
Address address = new InternetAddress("[email protected]");
Taller Aplicaciones Web con JSP
Dante Mendoza Ruelas
Si queremos que aparezca el nombre junto a la dirección e-mail, también
podemos pasárselo al constructor:
Address address = new InternetAddress("[email protected]", "Dante");
Necesitaremos crear objetos address para los campos from y to del mensaje. A
menos que el servidor lo evite, no hay nada que nos impida enviar un mensaje
que parezca que viene de otra persona.
Una vez que hemos creado las direcciones, las conectamos al mensaje de una
de estas dos formas. Para identificar al que lo envía, usamos los métodos
setFrom() y setReplyTo().
message.setFrom(address)
Si nuestro mensaje necesita varias direcciones "from", usamos el método
addFrom():
Address address[] = ...;
message.addFrom(address);
Para identificar a los receptores del mensaje, usamos el método
addRecipient(). Este método requiere un Message.RecipientType junto a la
dirección.
message.addRecipient(type, address)
Los tres tipos predefinidos de direcciones son:



Message.RecipientType.TO
Message.RecipientType.CC
Message.RecipientType.BCC
Por eso, si el mensaje fuera dirigido a alguien con copia a otra persona, esto
sería lo apropiado:
Address toAddress = new InternetAddress("[email protected]");
Address ccAddress = new InternetAddress("[email protected]");
message.addRecipient(Message.RecipientType.TO, toAddress);
message.addRecipient(Message.RecipientType.CC, ccAddress);
Taller Aplicaciones Web con JSP
Authenticator
Dante Mendoza Ruelas
Para usar el Authenticator, subclasificamos la clase abstracta y devolvemos un
ejemplar PasswordAuthentication del método getPasswordAuthentication().
Debemos registrar el Authenticator con la sesión cuando se crea. Luego,
nuestro Authenticator será notificado cuando sea necesaria una
autentificación.
Transport
La parte final del envío de un mensaje es usar la clase Transport. Estas clase
habla el lenguaje específico del protocolo para enviar mensajes (normalmente
SMTP). Es una clase abstracta y funciona como Session.
Podemos usar la versión por defecto de la clase sólo llamando al método
estático send():
Transport.send(message);
Store y Folder
Obtener los mensajes empieza de forma similar a enviar mensajes, con una
Session.
// Store store = session.getStore("imap");
Store store = session.getStore("pop3");
store.connect(host, username, password);
Después de conectar al Store, podemos obtener un Folder, que debe estar
abierto antes de poder leer los mensajes que hay en su interior:
Folder folder = store.getFolder("INBOX");
folder.open(Folder.READ_ONLY);
Message message[] = folder.getMessages();
Para POP3, la única carpeta disponible es INBOX. Si estamos usando IMAP,
podremos disponer de otras carpetas.
Una vez que tenemos un Message para leer, podemos obtener sus contenidos
con getContent() o escribir sus contenidos en un stream con writeTo().
Después de haber leído el e-mail, cerramos la conexión al folder y al store.
folder.close(aBoolean);
store.close();
Taller Aplicaciones Web con JSP
Dante Mendoza Ruelas
El valor boleano pasado al método close() del folder significa si actualizamos o
no la carpeta eliminando los mensajes borrados.
Ejercicio:
<%@ page import = "java.util.Properties" %>
<%@ page import = "javax.mail.*" %>
<%@ page import = "javax.mail.internet.*" %>
<%
// Obtener las propiedades del sistema
Properties props = System.getProperties();
// Armar el servidor
props.put("mail.smtp.host", "smtp.mail.yahoo.com.mx");
props.put("mail.smtp.auth", "true");
//Authenticathor
Authenticator auth = new Authenticator(){
private PasswordAuthentication pwdAuth = new
PasswordAuthentication("ing_dantemr", "xxx");
protected PasswordAuthentication getPasswordAuthentication() { return
pwdAuth;
}
};
// Obtener una sesion
Session misesion = Session.getDefaultInstance(props, auth);
// Definir el mensaje
MimeMessage message = new MimeMessage(misesion);
message.setFrom(new InternetAddress("[email protected]"));
message.addRecipient(Message.RecipientType.TO, new
InternetAddress("[email protected]"));
message.setSubject("Hello JavaMail");
message.setText("Welcome to JavaMail");
// Enviar el mensaje
Transport.send(message);
%>