42
Java Servlets -2011 1 SERVLETS MARIO OSVALDO BRESSANO

Teoría servlets

Embed Size (px)

DESCRIPTION

Java Servlets

Citation preview

  • 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