Teoría servlets
-
Upload
julian-aiup -
Category
Documents
-
view
252 -
download
0
description
Transcript of Teoría servlets
-
Java Servlets -2011
1
SERVLETS MARIO OSVALDO BRESSANO
-
Java Servlets -2011
2
Qu es un Servlet?
Interaccin 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 segn un modelo
cliente/servidor.
Al escribir la direccin de un sitio web o una URL en un navegador, o cliente, se inicia una peticin
al servidor que almacena al sitio. Cualquier accin que realice el servidor es transparente para los
visitantes del sitio. En una arquitectura cliente/servidor tpica de 2-capas, el contenido del sitio web
(la capa de presentacin del sitio web) como las pginas 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 ms 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 extensin del modelo cliente/servidor 2-capas a una
aproximacin 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 (Edicin
Empresarial de Java 2). Este modelo es el implementado en servidores de aplicacin como el
WebSphere de IBM, el BEA WebLogic, Tomcat del Proyecto Jakarta, Sun One Aplication Server;
Internet Information Server de Microsoft, etc.
-
Java Servlets -2011
3
Figura 2: Arquitectura de N-capas
La aproximacin de N-capas es ideal para la generacin de contenido dinmico. Los Servlets de
Java, que heredan las caractersticas de Java y ms, 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 mayora del contenido que se enva al cliente es texto esttico, marcas y solo una pequea parte
de contenido dinmico. En cambio los servlets, son utilizados cuando la cantidad de texto esttico y
marcas es pequeo. 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 tecnologa Java que se usa
para implementarlos. Los Servlets incrementan la funcionalidad de una aplicacin web. Se cargan
de forma dinmica por el entorno de ejecucin Java del servidor cuando se necesitan. Cuando se
recibe una peticin del cliente, el contenedor/servidor web inicia el servlet requerido. El Servlet
procesa la peticin del cliente y enva 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.
-
Java Servlets -2011
4
Figura 3: Modelo de respuesta a peticiones HTTP
La interaccin cliente/servidor basada en Web usa el protocolo HTTP. EL protocolo HTTP es un
protocolo sin estados basado en un modelo de peticin y respuesta con un nmero pequeo y finito
de mtodos de peticin como GET, POST, HEAD, OPTIONS, PUT, TRACE, DELETE, CONNECT, etc..
La respuesta contiene el estado de la respuesta y meta-informacin describiendo dicha respuesta.
La mayor parte de las aplicaciones web basadas en servlets se construyen en el marco de trabajo
del modelo peticin/respuesta HTTP.
Los Servlets permiten:
1- Leer datos enviados por los usuarios (formularios web o subprogramas applet-)
2- Buscar cualquier tipo de informacin respecto a la peticin HTTP (nombre del host,
cookies)
3- General resultados en una conexin a la Db por medio de CORBA (Common Object
Request Broker Architecture arquitectura comn de intermediarios en peticiones
a objetos) O RMI (Remote Method Invocation Llamada a mtodos remotos) la
diferencia consiste en el que el primero permite llamar aplicaciones escritas en otros
lenguajes)
4- Dar formato a los resultados
5- Establecer parmetros HTTP adecuados a la respuestas
6- Devolver el documento al cliente.
Comparacin con los CGI (Interfaz de compuerta comn)
a- EFICIENTES: Pues en los CGI cada peticin genera un proceso
-
Java Servlets -2011
5
b- ADECUADOS: Analizan y decodifican automticamente cdigo HTML, cookies, rastrear
sesiones, etc.
c- PODEROSOS: Se comunican directamente con el servidor web
d- TRANSPORTABLES: Al estar escritos en Java, poseen un cdigo estndar.
e- SEGUROS: Son ejecutados por la mquina virtual con su respectiva seguridad.
f- ECONMICOS: Para ejecutarse no requiere software propietario.
Requerimientos de Ejecucin de los Servlets Java
1. Los Servlets de Java requieren algn conocimiento previo de Java y HTML
2. Las aplicaciones web y las pginas web que requieran iniciacin 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 tambin pueden
ejecutarse en servidores de aplicacin 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
especificacin Java Servlet 2.1 o 2.2.
4. Una vez que el contenedor/servidor bsico se ha bajado y configurado, el siguiente paso es
entender la programacin 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
ms especfico 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 bsicas y
los interfaces usados en la implementacin 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 peticin uno, generando un
subproceso ES UNA DIFERENCIA CON EL CGI) y luego al finalizar DESTROY.
-
Java Servlets -2011
6
Public Interface Servlet
Todo servlet debe directa o indirectamente implementar este interfaz. Como cualquier otro interfaz
de Java, este es tambin una coleccin de declaraciones vacas de mtodos. Los siguientes
mtodos estn declarados en el interfaz Servlet.
1. public abstract void init (ServletConfig config) throws ServletException.
El mtodo init se usa para inicializar los parmetros proporcionados por el objeto
ServletConfig. Se invoca slo una vez, a menos que el servlet sea reiniciado si se destruye
y se vuelve a cargar. El mtodo init es el lugar en el que inicializar los parmetros de
configuracin como la conexin con una base de datos, la inicializacin de archivos y otros
valores de entorno. Ninguno mtodo del servlet puede ser invocado a no ser que el servlet
est inicializado mediante el uso del mtodo init().
2. public abstract ServletConfig getServletConfig ()
Este mtodo proporciona el objeto ServletConfig para la inicializacin de los parmetros del
servlet. Se pueden crear parmetros adicionales especificndolos 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 mtodo service es el punto esencial del modelo peticin respuesta del protocolo HTTP.
Recibe una peticin del cliente en forma de objeto ServletRequest. Los parmetros del
cliente son pasados junto al objeto de peticin (aunque existen otras formas de enviar
parmetros desde el cliente al servlet, por ejemplo, usando cookies o por medio de una
reescritura del URL). La respuesta resultante se enva al cliente usando el objeto
ServletResponse.
4. public abstract String getServletInfo()
Este mtodo se usa para la extraccin de metadatos del servlet, como por ejemplo el autor,
la versin del servlet, y otra informacin concerniente al copyright. El mtodo tendr que
ser redefinido dentro del servlet para que devuelva esta informacin.
-
Java Servlets -2011
7
5. public abstract void destroy ()
El mtodo destroy se invoca para liberar todos los recursos solicitados como la base de
datos, y otros recursos del servidor. Tambin se encarga de la sincronizacin de cualquier
hilo pendiente. Este mtodo se llama una sola vez, automticamente, como el mtodo init.
La clase GenericServlet proporciona una implementacin bsica del interfaz Servlet. Para escribir un
servlet especificamente para el protocolo HTTP, se usa la clase HTTPServlet, que extiende a
Generic Servlet.
1. El mtodo destroy se invoca para liberar todos los recursos solicitados como la base de
datos, y otros recursos del servidor. Tambin se encarga de la sincronizacin de cualquier
hilo pendiente. Este mtodo se llama una sola vez, automticamente, como el mtodo init.
La clase GenericServlet proporciona una implementacin bsica 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 mtodo init (1). Si un
cliente ha enviado una peticin al contenedor web, entonces, esa peticin se pasa al mtodo
servicio del servlet (2), y se envia una respuesta de vuelta al contendor web (3). Finalmente,
cuando el servlet haya finalizado su propsito, el contenedor web invoca al mtodo destroy (4).
-
Java Servlets -2011
8
Figura 5: Ciclo de Vida del Servlet
web.xml.
web.xml es un archivo escrito en XML que describe diversas caractersticas del archivo WAR, a
continuacin se describen sus elementos bsicos.
hola
com.osmosislatina.Saludos
hola
/visitas
hola
/despedida
hola
*.do
-
Java Servlets -2011
9
index.jsp
index.html
bienvenida.jsp
El primer elemento indica el inicio de la aplicacin, es dentro de este elemento que
se definen todos los elementos restantes.
El elemento define las caractersticas de un Servlet y a su vez est compuesto por los
elementos y 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 el cual define la ubicacin en trminos
de directorios de un sitio (URL), esto es, el elemento hola esta
indicando que el Servlet llamado hola ser accesado cada vez que se accese el directorio base
/visitas .
Ntese 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 cuestin (hola) .
Finalmente el elemento indica que cuando se solicite cualquier directorio sin
indicar un archivo en especifico se enve el archivo llamado: index.jsp, index.html o index.htm,
donde el primero tiene preferencia en caso de existir ms de un archivo en la lista.
Lo anterior son solo los parmetros bsicos utilizados en web.xml, a continuacin 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;
-
Java Servlets -2011
10
import javax.servlet.ServletException;
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 lgica de
serializacin, 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 aplicacin que serializa en disco una serie de objetos al
cerrarse y los lee en la siguiente ejecucin para mantener los valores que tenan antes. En un
momento dado, modificas una de las clases aadiendo un atributo nuevo. Al ejecutar esta versin
de la aplicacin 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
exista) y tu aplicacin "tericamente" va a leer datos corruptos puesto que "tericamente" no
puede saber que la clase ha cambiado (veremos que si puede saberlo). El campo serialVersionUID
es el nmero de versin 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 excepcin 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
-
Java Servlets -2011
11
ellas (este es tu caso). El valor es indiferente, pero debes actualizarlo cada vez que modificas tu
clase aadiendo o quitando atributos (lo ms sencillo en incrementarlo en 1). Si el programador no
indica este campo la JVM aade uno por su cuenta, sin embargo no es demasiado conveniente
permitir esto (al cambiar ligeramente el programa o cambiar la JMV podra 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 mtodo Service para las dos peticiones ms
comunes del HTTP: get y post.
Una peticin GET obtiene informacin del servidor recuperando la misma en un documento HTML
o una imagen.
En cambio una peticin POST publica o enva datos de un servidor.
Dentro de la clase HttpServlet existen estos mtodos:
1. doDelete (borrar archivos)
2. doHead (procesar encabezados)
3. doOptions (devuelve informacin al cliente sobre el servidor)
4. doPut (almacena archivos)
5. doTrace (depuracin)
public void doGet(HttpServletRequest request, HttpServletResponse response) throws
ServletException, IOException {:
Los mtodos 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 mtodo Service
que a su vez se lo pasa a doGet o doPost segn corresponda, conteniendo la peticin del cliente.
Por otra parte se invoca throws ServletException, IOException que se ejecutarn:
-
Java Servlets -2011
12
String getParameter(String nombre): Nos devuelve el valor del parmetro cuyo nombre le
indicamos. Si la variable no existiera o no tuviese ningn valor, devolvera null
Enumerate getParameterNames(): Nos devuelve una enumeracin de los nombres de los
parmetros que recibe el servlet.
Enumerate getParameterValues(String): Nos devuelve los valores que toma un parmetro
dado, esto es til para listas de seleccin mltiple donde un parmetro tiene ms 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 cdigo 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();
-
Java Servlets -2011
13
String docType = "
Manejo de una peticin Get de HTTP
Haga clic en el botn para invocar el servlet
//ARCHIVO CEROSERVLET.JAVA
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
-
Java Servlets -2011
14
public class CeroServlet extends HttpServlet {
protected void doGet( HttpServletRequest peticion, HttpServletResponse respuesta )
throws ServletException, IOException {
respuesta.setContentType( "text/html" );
PrintWriter salida = respuesta.getWriter();
salida.println( "" );
salida.println( "" );
salida.println( "" );
salida.println( "" );
salida.println( "Un ejemplo de servlet simple" );
salida.println( "" );
salida.println( "" ); salida.println( "Bienvenido a los servlets!" );
salida.println( "" );
salida.println( "" );
salida.close(); // cerrar flujo para completar la pgina }
}
Si llamamos un servlet desde un formulario HTML, podremos hacerlo de dos formas: GET y POST. Con la primera los parmetros del formulario estn incluidos la url que se utiliza para
invocar el servlet y en el segundo caso los parmetros se almacenan en un buffer especial del servidor.
Para procesar el primer tipo de peticiones (GET) est el mtodo doGet mientras que para el segundo tenemos el mtodo doPost . La implementacin por defecto del mtodo service es
capaz de determinar el tipo de peticin HTTP que en un momento dado recibe el servlet. Una vez identificada llama o al mtodo doGet o al doPost segn el caso.
Ejemplo 4: Uso de doGet y doPost
Podemos observar que el mtodo init es pblico, no devuelve ningn tipo (void), que puede lanzar
una excepcin (ServletException) y que tiene un parmetro (ServletConfig conf). De estos dos
ltimos aspectos (excepcin y parmetro) no nos tenemos que preocupar pues es el servidor quien
ejecuta el mtodo init. En el peor de los casos, tendramos que lanzar la excepcin (si sabemos
-
Java Servlets -2011
15
hacerlo), si por algn motivo el mtodo init que nosotros implementemos falle (por ejemplo, que no
se pueda conectar a la base de datos y evitamos mostrar un mensaje de error)
Lo siguiente que hacemos redefinir el mtodo service, cuando el servidor web recibe una peticin
para un servlet llama al mtodo public void service(HttpServletRequest req, HttpServletResponse
res) con dos parmetros: el primero, de la clase HttpServletRequest, representa la peticin del
cliente y el segundo, de la clase HttpServletResponse, representa la respuesta del servidor (del
servlet, ms 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("");
out.println(""); out.println("LLAMADA POR GET");
out.println(req.getParameter("nombre")); out.println("");
out.println(""); }
public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException
{ res.setContentType("text/html");
PrintWriter out = res.getWriter();
out.println(""); out.println("");
out.println("LLAMADA POR POST"); out.println(req.getParameter("nombre"));
out.println("");
out.println(""); }
}
Formulario que llama a GetPostJava
-
Java Servlets -2011
16
Mtodo GET Y POST
Nombres:
Nombres:
Ejemplo 6: Uso de doPost implementado con doGet
import java.io.IOException;
-
Java Servlets -2011
17
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("");
out.println("Mi Primer Servlet ");
out.println(""); out.println("Este es mi Primer Servlet");
out.println(""); }
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 mtodo init y cada vez que un cliente acceda al servlet el servidor llamar al mtodo 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 despus service, pero ... Y la segunda vez y sucesivas tambin se llama a init o slo a service?.
Normalmente, el servidor crea el servlet (llama, por tanto, al mtodo 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 nmero de visitas que recibe, para ello nos
bastar crear una variable contador que inicializaremos en el mtodo 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.*;
-
Java Servlets -2011
18
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 {
res.setContentType("text/html");
PrintWriter out = res.getWriter();
int tmp = contador;
//incrementamos la variable contador
contador++;
-
Java Servlets -2011
19
out.println("");
out.println("");
out.println("Numero de peticiones " + tmp +"");
out.println("");
out.println("");
}
public void doPost(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
doGet(req, res);
}
}
Un mismo servlet puede ser llamado por ms de un cliente a la vez. En este caso, el servidor crea
una hebra del servlet por cada peticin y esas dos hebras accedern concurrentemente a los
mismos datos (la variable contador). Como la lectura e incremento de contador no es una
operacin atmica, se podra utilizar la primitiva de sincronizacin syncronized para que se realice
de forma atmica:
//Archivo Contador2
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
-
Java Servlets -2011
20
public class Contador2 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 {
res.setContentType("text/html");
PrintWriter out = res.getWriter();
int tmp;
synchronized(this) {
//leemos el contador
tmp = contador;
//incrementamos la variable contador
contador++;
-
Java Servlets -2011
21
}
out.println("");
out.println("");
out.println("Numero de peticiones " + tmp +"");
out.println("");
out.println("");
}
public void doPost(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
doGet(req, res);
}
}
Ejemplo 8: Uso de un servlet para redireccionado de pginas en Internet.
Podemos trabajar de dos maneras:
1- Con una pgina htm que por medio de hipervnculos me dirija al lugar deseado
-
Java Servlets -2011
22
Redireccionar una peticin hacia otro sitio
Haga clic en un vnculo para redireccionarlo a la pgina apropiada
www.mariobressano.com.ar
Servlet de bienvenida
2- Por medio de un formulario que me permita seleccionar el lugar deseado
FORMULARIO PARA ENVO DE DATOS A
-
Java Servlets -2011
23
.style1 {
font-family: Tahoma;
font-size: large;
text-align: center;
}
.style2 {
color: #000080;
}
.style6 {
font-family: Tahoma;
font-size: small;
}
REDIRECCION POR FORMULARIO
-
Java Servlets -2011
24
Indicar Pgina
MARIOBRESSANO
PRIMERA
-
Java Servlets -2011
25
//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
{
-
Java Servlets -2011
26
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" );
// cdigo que se ejecuta solamente si este servlet
// no redirecciona al usuario hacia otra pgina
respuesta.setContentType( "text/html" );
PrintWriter salida = respuesta.getWriter();
// empezar documento de XHTML
salida.println( "" );
salida.println( "" );
salida.println(
"" );
// seccin de encabezado del documento
salida.println( "" );
salida.println( "Pgina invlida" );
salida.println( "" );
// seccin del cuerpo del documento
-
Java Servlets -2011
27
salida.println( "" );
salida.println( "Solicit una pgina invlida" );
salida.println( "" );
salida.println( "Haga clic aqu para seleccionar de nuevo" );
salida.println( "" );
// fin del documento de XHTML
salida.println( "" );
salida.close(); // cerrr flujo para completar la pgina
}
}
Ejemplo 9: Uso de un servlet para levantar datos de un formulario confeccionado en html
Formulario para ingreso de datos
Introduce tus datos:
Nombre:
-
Java Servlets -2011
28
Edad:
Formulario de Datos
//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 {
res.setContentType("text/html");
PrintWriter pw = res.getWriter();
pw.println("Leyendo parmetros");
pw.println("");
pw.println("Leyendo parmetros desde un formulario html");
pw.println("\n");
pw.println("Te llamas " + req.getParameter("NOM") + "");
pw.println("y tienes " + req.getParameter("EDA") + " aos");
-
Java Servlets -2011
29
pw.println("");
pw.close();
}
public void doPost(HttpServletRequest req, HttpServletResponse res) throws
ServletException, IOException {
doGet(req,res);
}
}
Normalmente los servlets tendrn parmetros o fuentes de informacin que le darn su aspecto dinmico. Es decir, para generar una simple pgina HTML no nos complicamos tanto la vida, se
escribe la pgina HTML y se ha terminado. Las fuentes de informacin 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 parmetros que le pase el cliente. De todas estas fuentes, nos interesan los accesos a bases de datos que veremos ms adelante y los parmetros que nos pasa el cliente
mediante formularios HTML.
Cuando pasamos parmetros a travs de un formulario, en los Servlets a travs de la clase
ServletRequest, disponemos de los siguientes mtodos para su tratamiento:
String getParameter(String nombre): Nos devuelve el valor del parmetro cuyo nombre le indicamos. Si la variable no existiera o no tuviese ningn valor, devolvera null
Enumerate getParameterNames(): Nos devuelve una enumeracin de los nombres de los
parmetros que recibe el servlet.
Enumerate getParameterValues(String): Nos devuelve los valores que toma un parmetro
dado, esto es til para listas de seleccin mltiple donde un parmetro tiene ms de un valor
FORMULARIO PARA ENVO DE DATOS A
.style1 {
-
Java Servlets -2011
30
font-family: Tahoma;
font-size: large;
text-align: center;
}
.style2 {
color: #000080;
}
.style6 {
font-family: Tahoma;
font-size: small;
}
FORMULARIO PARA ENVO DE DATOS A SERVLET:
Nombres
Apellido
Domicilio
-
Java Servlets -2011
31
Telfono
E-mail
Tarjeta de Crdito
VISA
MASTERCARD
AMERICAN
EXPRESS
Observaciones
-
Java Servlets -2011
32
//Archivo CuartoServlet.java- Levanta datos del formulario anterior
import java.io.*;
import java.util.*;
import javax.servlet.*;
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();
-
Java Servlets -2011
33
String docType = "
-
Java Servlets -2011
34
}
out.println("");
}
public void doPost(HttpServletRequest req, HttpServletResponse res) throws
ServletException, IOException {
doGet(req,res);
}
}
En el caso de HttpServlet la implementacin por defecto del mtodo service comprueba si la
peticin recibida era de tipo POST (los parmetros se pasan en la cabecera del mensaje) o de tipo
GET (los parmetros estn en la URL, luego son visibles para todo el mundo), y llama a los
mtodos doPost o doGet dependiendo de esto.
Tanto doGet como doPost reciben como parmetros objetos de tipo HttpServletRequest y
HttpServletResponse.
ACCESO A BASE DE DATOS
Antes de comenzar, algunas aclaraciones:
El problema es comunicar un programa o aplicacin con una base de datos y ms que comunicar se
pretende que el programa o aplicacin 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 fsicamente en el servidor y en alguna carpeta o directorio del disco
duro de dicha mquina.
Tambin es necesario conocer que as como existen servidores de pginas (web server), servidores
de correo (mail server), servidores de ftp (ftp server), etc., tambin existen servidores de bases de
datos (database server), los ms comunes son el sqlserver de Microsoft, Oracle, Mysql, etc., estos
servidores tambin pueden crear, administrar y procesar una base de datos.
-
Java Servlets -2011
35
El modo de comunicarse entre nuestro programa o aplicacin y la base de datos implica que
ambos manejen un lenguaje de programacin comn, es decir, no se puede mandar una
instruccin en C Sharp, o en Basic o Pascal, a la base de datos y adems esperar que esta ultima la
entienda (una razn muy sencilla es que la base de datos tendra que conocer o comprender todos
los lenguajes de programacin), para resolver este problema de comunicacin es que se usa un
lenguaje comn de bases de datos que tanto los lenguajes de programacin existentes como las
bases de datos entienden, este lenguaje comn 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.
Cmo 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 conexin o enlace a la base de
datos.
OBJETO RESULTSET: Es la representacin 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 realmente
contra un resulset y no provocan ningn cambio en la tabla fsica en disco, resulset tiene un
conjunto de mtodos muy tiles y muy usados para el proceso de los renglones de la tabla virtual.
OBJETO STATEMENT: Este objeto y sus dos mtodos executequery (para select de SQL) y
executeupdate (para insert, update y delete de SQL) son los mtodos que se utilizaran para
comunicarse con la tabla fsica en disco.
createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE
)
Una de las nuevas caractersticas del API JDBC 2.0 es la habilidad de mover el cursor en una hoja
de resultados tanto hacia atrs como hacia adelante. Tambin hay mtodos que nos permiten
mover el cursor a una fila particular y comprobar la posicin del cursor. La hoja de resultados
Scrollable hace posible crear una herramienta GUI (Interface Grfico de Usuario) para navegar a
-
Java Servlets -2011
36
travs de ella, lo que probablemente ser uno de los principales usos de esta caracterstica. 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 slo lectura o actualizable: CONCUR_READ_ONLY y CONCUR_UPDATABLE. Lo que
debemos recordar aqu es que si especificamos un tipo, tambin debemos especificar si es de slo
lectura o actualizable. Tambin, debemos especificar primero el tipo, y como ambos parmetros
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 slo se mueve hacia adelante. Si no se especifican constantes
para el tipo y actualizacin de un objeto ResultSet, obtendremos automticamente una
TYPE_FORWARD_ONLY y CONCUR_READ_ONLY (exactamente igual que en el API del JDBC 1.0).
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 mtodos 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 harn
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
ms detalle ms adelante. Aunque deberamos 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 crebamos un
objeto ResultSet anteriormente, tena el cursor posicionado antes de la primera fila. Incluso aunque
-
Java Servlets -2011
37
una hoja de resultados se seleccione desplazable, el cursor tambin se posiciona inicialmente
delante de la primera fila. En el API JDBC 1.0, la nica forma de mover el cursor era llamar al
mtodo next. Este mtodo todava es apropiado si queremos acceder a las filas una a una, yendo
de la primera fila a la ltima, pero ahora tenemos muchas ms formas para mover el cursor.
La contrapartida del mtodo next, que mueve el cursor una fila hacia delante (hacia el final de la
hoja de resultados), es el nuevo mtodo previous, que mueve el cursor una fila hacia atrs (hacia
el inicio de la hoja de resultados). Ambos mtodos devuelven false cuando el cursor se sale de la
hoja de resultados (posicin antes de la primera o despus de la ltima fila), lo que hace posible
utilizarlos en un bucle while. Ye hemos utilizado un mtodo 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 mtodo next devuelva false. El siguiente fragmento de cdigo 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()) {
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 mtodos first, last,
beforeFirst, y afterLast mueven el cursor a la fila indicada en sus nombres. El mtodo absolute
mover el cursor al nmero de fila indicado en su argumento. Si el nmero es positivo, el cursor se
mueve al nmero dado desde el principio, por eso llamar a absolute(1) pone el cursor en la primera
fila. Si el nmero es negativo, mueve el cursor al nmero dado desde el final, por eso llamar a
absolute(-1) pone el cursor en la ltima fila. La siguiente lnea de cdigo mueve el cursor a la
cuarta fila de srs.
srs.absolute(4);
Si srs tuviera 500 filas, la siguiente lnea de cdigo movera el cursor a la fila 497.
srs.absolute(-4);
-
Java Servlets -2011
38
Tres mtodos mueven el cursor a una posicin relativa a su posicin actual. Como hemos podido
ver, el mtodo next mueve el cursor a la fila siguiente, y el mtodo previous lo mueve a la fila
anterior. Con el mtodo relative, se puede especificar cuntas filas se mover desde la fila actual y
tambin la direccin en la que se mover. Un nmero positivo mueve el cursor hacia adelante el
nmero de filas dado; un nmero negativo mueve el cursor hacia atrs el nmero de filas dado. Por
ejemplo, en el siguiente fragmente de cdigo, 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 mtodo getRow permite comprobar el nmero de fila donde est el cursor. Por ejemplo, se
puede utilizar getRow para verificar la posicin actual del cursor en el ejemplo anterior.
srs.absolute(4);
int rowNum = srs.getRow(); // rowNum debera ser 4
srs.relative(-3);
int rowNum = srs.getRow(); // rowNum debera ser 1
srs.relative(2);
int rowNum = srs.getRow(); // rowNum debera ser 3
Existen cuatro mtodos adicionales que permiten verificar si el cursor se encuentra en una posicin
particular. La posicin se indica en sus nombres:isFirst, isLast, isBeforeFirst, isAfterLast. Todos
estos mtodos devuelven un boolean y por lo tanto pueden ser utilizados en una sentencia
condicional. Por ejemplo, el siguiente fragmento de cdigo comprueba si el cursor est despus de
la ltima fila antes de llamar al mtodo previous en un bucle while. Si el mtodo isAfterLast
devuelve false, el cursor no estar despus de la ltima fila, por eso se llama al mtodo afterLast.
Esto garantiza que el cursor estar despus de la ltima fila antes de utilizar el mtodo previous en
el bucle while para cubrir todas las filas de srs.
if (srs.isAfterLast() == false) {
srs.afterLast();
}
while (srs.previous()) {
-
Java Servlets -2011
39
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;
public void init(ServletConfig conf) throws ServletException {
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);
-
Java Servlets -2011
40
//Decimos que nos hemos conectado
out.println("");
out.println("");
out.println("Hemos conectado!");
out.println("");
out.println("");
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());
}
finally {
//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("");
out.println("NOMBREdocumento");
while(tabla.next()) {
-
Java Servlets -2011
41
out.println("");
out.println(""+tabla.getString(1)+"");
out.println(""+tabla.getString(2)+"");
out.println("");
};
out.println("CERRAMOS LA TABLA Y
FINALIZAMOS");
tabla.close(); }
catch(SQLException e) {};
}
}
public void doPost(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
doGet(req, res);
}
}
Bibliografa:
Ttulo: Java. Cmo programar. Quinta Edicin
Autor: Deitel.
Editorial: Pearson. Pretince Hall Ttulo: Programacin en Java 2
Autor: Luis Aguilar e Ignacio Zahonero Martnez Editorial: Mc. Graw Hill Ttulo: Programacin con Java Autor: Decaer - Hirshfield
Editorial: Thompson Learning
Web: Java en castellano http://www.programacion.com
___________________________________________________________Mario O. Bressano______
-
Java Servlets -2011
42