Tema servlets

121
Tema Servlets DESARROLLADO X : HUAMANCHAO GOMEZ SIMEON

description

 

Transcript of Tema servlets

Page 1: Tema servlets

Tema Servlets

DESARROLLADO X : HUAMANCHAO GOMEZ SIMEON

Page 2: Tema servlets

Introducción

Necesidad de mecanismos para desarrollar “aplicaciones web” contenido dinámico

Cuando escribes una URL en tu navegador: El navegador establece una conexión TCP/IP

con el servidor El navegador envía una petición al servidor El servidor devuelve una respuesta al

cliente El servidor cierra la conexión

Los mensajes intercambiados entre el cliente y el servidor son HTTP

Page 3: Tema servlets

HTTP

Especificación de HTTP: http://www.w3.org/Protocols/rfc2616/rfc2616.html

Básicamente debemos saber que los comandos principales son HTTP GET y POST.

Page 4: Tema servlets

Tecnología Servlet

Piedra angular del desarrollo de aplicaciones web en Java Los JSPs son de hecho servlets

“disfrazados”

Page 5: Tema servlets

Características de los Servlets

Pensados para reemplazar a los CGIs Cada petición de un cliente hacía al

servidor lanzar un nuevo proceso con el programa CGI

No es la única tecnología disponible:

ASP.NET PHP (plataforma LAMP)

Page 6: Tema servlets

Ventajas

Rendimiento cada petición es procesada por un único proceso en el contenedor de servlets

Portabilidad heredado de Java Rápido desarrollo acceso a las

riquísimas librerías de Java Robustez gestionados por la

máquina virtual de Java (garbage collection)

Amplio soporte muchos desarrolladores y compañías utilizan esta tecnología

Page 7: Tema servlets

Arquitectura

Servlet Container = servidor web capaz de ejecutar servlets

En una aplicación JSP, el contenedor se corresponde a un JSP container.

Browser HTTP ServerServlet Container

Contenido Estático

ServletHTTP Request

HTTP Response

Page 8: Tema servlets

Funcionamiento de un Servlet

Recibir Petición

¿Está el Servidor

Cargado?

¿Es el servidor reciente?

Procesar Petición

Enviar Respuesta

Cargar Servlet

NO

NO

Page 9: Tema servlets

Contenedor Tomcat 5

El contenedor de Servlets más popular

Actualmente en la versión 5.0 Open source, disponible en:

http://jakarta.apache.org/tomcat/ Vamos a instalarlo ...

Page 10: Tema servlets

Instalando Tomcat 5

Requisitos: Haber instalado Java 5

Extraer fichero: downloads\Tomcat5.5\jakarta-tomcat-5.5.7.zip

Crear las siguientes variables de entorno, por medio de Panel de Control->Sistema->Avanzado->Variables de Entorno: TOMCAT_HOME=<TOMCAT_INSTALL_DIR>

Page 11: Tema servlets

6 Pasos Para Crear tu Primer Servlet

1. Crear una estructura de directorios bajo Tomcat para tu aplicación

2. Escribir el código del servlet3. Compilar el código4. Crear un descriptor de explotación

(deployment descriptor)5. Ejecutar Tomcat6. Invocar el servlet desde un

navegador

Page 12: Tema servlets

Crear directorio bajo Tomcat para tu aplicación

El directorio %TOMCAT_HOME%/webapps es dónde cuelgas tus aplicaciones

Una aplicación web es un conjunto de servlets y otros recursos instalados bajo el espacio URL de un servidor

Pasos:1. Crear un directorio bajo webapps con el nombre de tu

aplicación ‘myapp’, que aparecerá en la url a tu aplicación

2. Crear el directorio WEB-INF debajo de ‘myApp’ Crear subdirectorio clases Crear subdirectorio lib

Podéis hacer copy/paste del contenido del directorio examples\servlets\ej1_holamundo_servlet bajo %TOMCAT_HOME\webapps\myapp

Vamos a reutilizar continuamente el contexto myapp

Page 13: Tema servlets

Escribir el Código del Servlet

// HelloWorldExample.java

import java.io.*;

import java.text.*;

import java.util.*;

import javax.servlet.*;

import javax.servlet.http.*;

public class HelloWorldExample extends HttpServlet {

public void doGet(HttpServletRequest request,

HttpServletResponse response)

throws IOException, ServletException

{

ResourceBundle rb =

ResourceBundle.getBundle("LocalStrings",request.getLocale());

response.setContentType("text/html");

PrintWriter out = response.getWriter();

out.println("<html>");

out.println("<head>");

String title = rb.getString("helloworld.title");

out.println("<title>" + title + "</title>");

out.println("</head>");

out.println("<body bgcolor=\"white\">");

out.println("<h1>" + title + "</h1>");

out.println("</body>");

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

}

}

Page 14: Tema servlets

Compilar el Código

Guardar el código en %TOMCAT_HOME%\webapps\myapp\WEB-INF\classes

Compilar el código:javac –classpath %TOMCAT_HOME%\common\lib\servlet-api.jar HelloWorldExample.java

Page 15: Tema servlets

Crear el web.xml

Nombre recibido por el deployment descriptor Debe colocarse en el directorio WEB-INF

web.xml es un documento XML que tiene como elemento raíz: <web-app>

Se pueden encontra n elementos <servlet> que cuelgan de él

Page 16: Tema servlets

Crear el web.xml

<?xml version="1.0" encoding="ISO-8859-1"?>

<!DOCTYPE web-app

PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"

"http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>

<display-name>Servlet 2.4 Examples</display-name>

<description>

Servlet 2.4 Examples.

</description>

<servlet>

<servlet-name>HelloWorldExample</servlet-name>

<servlet-class>HelloWorldExample</servlet-class>

</servlet>

<servlet-mapping>

<servlet-name>HelloWorldExample</servlet-name>

<url-pattern>/HelloWorldExample</url-pattern>

</servlet-mapping>

</web-app>

Page 17: Tema servlets

Ejecutar el Código

Arrancar Tomcat si es necesario, mediante el comando: %TOMCAT_HOME%\bin\catalina.bat run

Invocar al servlet: http://localhost:8080/myapp/HelloWorldExample

Page 18: Tema servlets

Resultado de Ejecutar Servlet

Page 19: Tema servlets

Servlets: Jerarquía

La jerarquía de clases java es...

Únicamente hay que hacer polimorfismo de los métodos que se quieran tratar.

Page 20: Tema servlets

Las APIs

Dos paquetes permiten la programación de servlets: javax.servlet javax.servlet.http

Revisar documentación: Arrancar Tomcat Visitar: http://localhost:8080

Page 21: Tema servlets

Servlets: Ciclo de vida

Ciclo de vida de un servlet:

Page 22: Tema servlets

Servlets: Ciclo de vida

Viene dado por tres métodos: init, service y destroy

INICIALIZACIÓN: Una única llamada al método “init” por parte del servidor. Incluso se pueden recoger unos parametros concretos con “getInitParameter” de “ServletConfig”.

SERVICIO: una llamada a service() por cada invocación al servlet ¡Cuidado! El contenedor es multihilo

DESTRUCCIÓN: Cuando todas las llamadas desde el cliente cesen o un temporizador del servidor así lo indique. Se usa el método “destroy”

Revisar documentación de la clase javax.servlet.Servlet

Page 23: Tema servlets

Demostrando el Ciclo de Vida

// examples\servlets\ej2_ciclovida_servlet

import javax.servlet.*;

import java.io.IOException;

public class CicloVidaServlet implements Servlet {

public void init(ServletConfig config) throws ServletException {

System.out.println("init");

}

public void service(ServletRequest request, ServletResponse response)

throws ServletException, IOException {

System.out.println("service");

}

public void destroy() {

System.out.println("destroy");

}

public String getServletInfo() {

return null;

}

public ServletConfig getServletConfig() {

return null;

}

}

Page 24: Tema servlets

Servlets: Operaciones duraderas

Respuestas a peticiónes de clientes que requieran de un tiempo de proceso muy largo.

Puede que el servlet deba destruirse y estas operaciones aun no hayan concluido.

Es responsabilidad del programador encargarse de su gestión.

Page 25: Tema servlets

Servlets: Operaciones duraderas

Necesitaremos por tanto: Mantener un seguimiento de las tareas

(threads) que se estén ejecutando en el método “service”

Proporcionar una finalización correcta haciendo que los procesos largos que aun no hayan concluido puedan terminar correctamente en el método “destroy” del servlet.

En ciertos casos poder terminar los procesos que aun siguen en ejecución si es necesario.

Page 26: Tema servlets

Servlets: Operaciones duraderas

Posible solución: Contadorpublic ShutdownExample extends HttpServlet {

private int serviceCounter = 0; private Object lock = new Object();  protected void enteringServiceMethod() {

synchronized(lock) { serviceCounter++; }} protected void leavingServiceMethod(){

synchronized(lock) {serviceCounter--;

if (serviceCounter == 0 && isShuttingDown()) notifyAll(); }} protected int numServices() {

synchronized(lock) { return serviceCounter; }}protected void service(HttpServletRequest req, HttpServletResponse resp)

throws ServletException, IOException {enteringServiceMethod(); try { super.service(req, resp); }

finally { leavingServiceMethod(); }}  

Page 27: Tema servlets

Servlets: Operaciones duraderas

Falta indicar la terminación.public ShutdownExample extends HttpServlet {

private boolean shuttingDown;

  protected void setShuttingDown(boolean flag) {

shuttingDown = flag;

}

protected boolean isShuttingDown() {

return shuttingDown;

public void destroy() {

synchronized(lock) {

if (numServices() > 0) {

setShuttingDown(true);

}

while(numServices() > 0) {

try { wait(); }

catch (InterruptedException e) { }

}

}

}

}  

Page 28: Tema servlets

Recuperando Configuración

Recuperando información de configuración del fichero web.xml

<servlet> <servlet-name>ConfigDemoServletExample</servlet-name> <servlet-class>ConfigDemoServlet</servlet-class> <init-param> <param-name>adminEmail</param-name> <param-value>[email protected]</param-value> </init-param> <init-param> <param-name>adminContactNumber</param-name> <param-value>6542214213</param-value> </init-param> </servlet>

Page 29: Tema servlets

Recuperando Configuración

Recuperando información de configuración del fichero web.xml, revisar ejemplo examples\servlets\ej3_configinfo_servlet

public class ConfigDemoServlet implements Servlet {ServletConfig cfg;public void init(ServletConfig config) throws ServletException {

this.cfg = config;Enumeration parameters =

config.getInitParameterNames();while (parameters.hasMoreElements()) {

String parameter = (String) parameters.nextElement();

System.out.println("Parameter name : " + parameter);

System.out.println("Parameter value : " + config.getInitParameter(parameter));

}}

// ...}

Page 30: Tema servlets

Contexto del Servidor

ServletContext representa el entorno donde se ejecuta el servidor, es decir, el Servlet Container Se puede obtener una referencia a él mediante el método

ServletConfig.getServletContext() Algunos métodos que se pueden utilizar son:

getMajorVersion de la Servlet API soportada por el contenedor

getMinorVersion setAttribute guarda un objeto en el ServletContext getAttributeNames getAttribute removeAttribute

A través del contexto de un servlet se puede compartir estado entre varios servlets.

Revisar ejemplo examples\servlets\ej4_contextinfo_servlet

Page 31: Tema servlets

Contexto del Servidor

ServletConfig servletConfig;

public void init(ServletConfig config) throws ServletException {

servletConfig = config;

}

public void service(ServletRequest request, ServletResponse response)

throws ServletException, IOException {

ServletContext servletContext = servletConfig.getServletContext();

Enumeration attributes = servletContext.getAttributeNames();

while (attributes.hasMoreElements()) {

String attribute = (String) attributes.nextElement();

System.out.println("Attribute name : " + attribute);

System.out.println("Attribute value : " +

servletContext.getAttribute(attribute));

}

System.out.println("Major version : " + servletContext.getMajorVersion());

System.out.println("Minor version : " + servletContext.getMinorVersion());

System.out.println("Server info : " + servletContext.getServerInfo());

}

Page 32: Tema servlets

Peticiónes y Respuestas

En el método service() los parámetros: ServletRequest representa la petición del cliente y ServletResponse la respuesta del servidor

ServletRequest tiene los siguientes métodos: getParameterNames getParameter getRemoteAddress getRemoteHost

ServletResponse tiene entre otros el método: getWriter

Revisar examples\servlets\ej5_requestresponse_servlet

Page 33: Tema servlets

Ejemplo ServletRequest y ServletResponse

public void service(ServletRequest request, ServletResponse response)

throws ServletException, IOException {

PrintWriter out = response.getWriter();

out.println("<HTML>");

// ...

out.println("<BR>Server Port: " + request.getServerPort());

out.println("<BR>Server Name: " + request.getServerName());

out.println("<BR>Protocol: " + request.getProtocol());

out.println("<BR>Character Encoding: " + request.getCharacterEncoding());

out.println("<BR>Content Type: " + request.getContentType());

out.println("<BR>Content Length: " + request.getContentLength());

out.println("<BR>Remote Address: " + request.getRemoteAddr());

out.println("<BR>Remote Host: " + request.getRemoteHost());

out.println("<BR>Scheme: " + request.getScheme());

Enumeration parameters = request.getParameterNames();

while (parameters.hasMoreElements()) {

String parameterName = (String) parameters.nextElement();

out.println("<br>Parameter Name: " + parameterName);

out.println("<br>Parameter Value: " +

request.getParameter(parameterName));

}

Enumeration attributes = request.getAttributeNames();

while (attributes.hasMoreElements()) {

String attribute = (String) attributes.nextElement();

out.println("<BR>Attribute name: " + attribute);

out.println("<BR>Attribute value: " + request.getAttribute(attribute));

}

out.println("</BODY>");

out.println("</HTML>");

}

Page 34: Tema servlets

Clase GenericServlet

El uso de la interfaz Servlet tiene dos inconvenientes: Hay que proveer implementaciones de

los cinco métodos de Servlet Hay que cachear la referencia a ServletConfig pasada como parámetro

La clase GenericServlet provee una implementación vacía de los 5 métodos de Servlet y recuerda ServletConfig

Page 35: Tema servlets

Ejemplo GenericServlet

import javax.servlet.*;

import java.io.IOException;

import java.io.PrintWriter;

public class SimpleServlet extends GenericServlet {

public void service(ServletRequest request, ServletResponse response)

throws ServletException, IOException {

PrintWriter out = response.getWriter();

out.println("<HTML>");

out.println("<HEAD>");

out.println("<TITLE>");

out.println("Extending GenericServlet");

out.println("</TITLE>");

out.println("</HEAD>");

out.println("<BODY>");

out.println("Extending GenericServlet makes your code simpler.");

out.println("</BODY>");

out.println("</HTML>");

}

}

Page 36: Tema servlets

Paquete javax.servlet.http

Normalmente siempre vamos a trabajar con él cuando programemos servlets.

Sus miembros y métodos son más convenientes y ofrecen más funcionalidad

Principalmente vamos a tratar con tres clases: HttpServlet HttpServletRequest HttpServletResponse

Page 37: Tema servlets

HttpServlet

Hereda de GenericServlet Tiene 6 métodos doXXX que son

invocados cada vez que el correspondiente comando HTTP es recibido: doPost doPut doGet doDelete doOptions doTrace

Page 38: Tema servlets

Servlets: Explicación de métodos HTTP

GET: Paso de parámetros en la propia URL de acceso al servicio o recurso del servidor. Método “doGet”GET /query.html?keyword='diego' HTTP/1.1Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-shockwave-flash, */*

Accept-Language: es,eu;q=0.7,en-gb;q=0.3Accept-Encoding: gzip, deflateUser-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322)

Host: localhost:9999Connection: Keep-Alive

Page 39: Tema servlets

Servlets: Explicación de métodos HTTP

POST: Lo mismo que GET pero los parámetros van en línea aparte dentro del cuerpo de la petición. El manejo es idéntico pero a través del método “doPost”.POST /cgi-bin/search.sh HTTP/1.1Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg,

application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-shockwave-flash, */*

Referer: http://localhost:9999/search.htmlAccept-Language: es,eu;q=0.7,en-gb;q=0.3Content-Type: application/x-www-form-urlencodedAccept-Encoding: gzip, deflateUser-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT

5.1; .NET CLR 1.1.4322)Host: localhost:9999Content-Length: 13Connection: Keep-AliveCache-Control: no-cache

keyword=diego

Page 40: Tema servlets

Servlets: Métodos

Por defecto retornan BAD_REQUEST(400) Son llamados desde el método

“service”. Reciben interfaces instanciadas:

“HttpServletRequest” para manejo de la informacion enviada por el usuario.

“HttpServletResponse” para poder enviar una respuesta en forma de pagina web.

Page 41: Tema servlets

Servlets: Respondiendo en HTML

2 pasos: Indicar una cabecera de respuesta de contenido

(antes de cualquier tipo de respuesta) Una manera es usando el método “setHeader” de

“HttpServletResponse”. Al ser un proceso tan común existe un método que nos

lo soluciona directamente: “setContentType” de “HttpServletResponse”.

Crear y enviar código HTML válido. Revisar examples\servlets\ej6_dogetdopost_servlet

Page 42: Tema servlets

Ejemplo doGet() y doPost()

// compile: javac -classpath %TOMCAT_HOME%\common\lib\servlet-api.jar DoGetDoPostServlet.java

import javax.servlet.*;

import javax.servlet.http.*;

import java.io.*;

public class DoGetDoPostServlet extends HttpServlet {

public void doGet(HttpServletRequest request,

HttpServletResponse response)

throws ServletException, IOException {

response.setContentType("text/html");

PrintWriter out = response.getWriter();

out.println("<HTML>");

out.println("<HEAD>");

out.println("<TITLE>The GET method</TITLE>");

out.println("</HEAD>");

out.println("<BODY>");

out.println("The servlet has received a GET. " +

"Now, click the button below.");

out.println("<BR>");

out.println("<FORM METHOD=POST>");

out.println("<INPUT TYPE=SUBMIT VALUE=Submit>");

out.println("</FORM>");

out.println("</BODY>");

out.println("</HTML>");

}

Page 43: Tema servlets

Ejemplo doGet() y doPost()public void doPost( HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); out.println("<HTML>"); out.println("<HEAD>"); out.println("<TITLE>The POST method</TITLE>"); out.println("</HEAD>"); out.println("<BODY>"); out.println("The servlet has received a POST. Thank

you."); out.println("</BODY>"); out.println("</HTML>"); }}

Page 44: Tema servlets

Servlets: Recogiendo la información de usuario.

2 formas de envío de información: En la línea URL mediante una ‘?’ En una línea separada.

En los antiguos CGIs el parseo era muy complejo. En Servlets usar “getParameter” de “HttpServletRequest” que devuelve “” (si no hay valor) o null (si no existe).

Page 45: Tema servlets

Servlets: Recogiendo la información de usuario

Si el parametro tiene mas de un valor se usa “getParameterValues” de “HttpServletRequest” que devuelve un array de strings.

Los nombres de los parametros son accesibles mediante “getParameterNames” de “HttpServletRequest” que devuelve un Enumeration de strings.

Se puede leer la línea directamente con “getReader” o “getInputStream” de “HttpServletRequest”.

Revisar: examples\servlets\ej7_listparams_servlet

Page 46: Tema servlets

Listando Parámetros Recibidos

// compile: javac -classpath %TOMCAT_HOME%\common\lib\servlet-api.jar PruebaServlet.java

import javax.servlet.*;

import javax.servlet.http.*;

import java.io.*;

import java.util.*;

public class PruebaServlet extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

response.setContentType("text/html");

PrintWriter out = response.getWriter();

out.println("<HTML>");

out.println("<HEAD>");

out.println("<TITLE>Obtaining the Parameter</TITLE>");

out.println("</HEAD>");

out.println("<BODY>");

out.println("The request's parameters are:<BR>");

Page 47: Tema servlets

Listando Parámetros Recibidos

Enumeration enumeration = request.getParameterNames();

while (enumeration.hasMoreElements()){

String parameterName = (String) enumeration.nextElement();

out.println(parameterName + ": " +

request.getParameter(parameterName) + "<BR>" );

}

out.println("<FORM METHOD=GET>");

out.println("<BR>First Name: <INPUT TYPE=TEXT NAME=FirstName>");

out.println("<BR>Last Name: <INPUT TYPE=TEXT NAME=LastName>");

out.println("<BR><INPUT TYPE=SUBMIT VALUE=Submit>");

out.println("</FORM>");

out.println("</BODY>");

out.println("</HTML>");

}

}

Page 48: Tema servlets

Servlets: Recogiendo la información de usuario

Cabeceras: Además de la información de la línea de petición, datos añadidos opcionales (excepto “Content-Length” en los métodos POST).

Accept Los tipos del formato MIME que acepta el navegador cliente.

Accept-Charset Los sets de caracteres que el navegador cliente espera.

Accept-Encoding Las codificaciónes de datos (por ejemplo gzip) que el navegador cliente soporta y conoce. Así el servlet puede consultar explícitamente información de codificación y así aprovechar las ventajas de HTML gzipeado indicándolo en la cabecera de respuesta Content-Encoding.

Page 49: Tema servlets

Servlets: Recogiendo la información de usuario

Accept-Language El lenguaje que el navegador cliente espera.

Authorization Información de autentificación, que generalmente se crea como respuesta a una cabecera WWW Authenticate enviada desde el servidor.

Connection Indica si se va a usar conexión persistente. Si un servlet recibe el valor Keep-Alive o una petición con una línea indicando HTTP 1.1 podrá hacer uso de las ventajas que estas ofrecen ahorrando tiempo en páginas con muchos elementos pequeños como imágenes o applets. El servlet ha de indicar el tamaño del contenido a enviar como respuesta mediante la cabecera Content-Length. Para ello se puede usar la clase ByteArrayOutputStream y al final enviar todos los datos.Content-Length Usada en los mensajes POST para indicar el tamaño de los datos.

Page 50: Tema servlets

Servlets: Recogiendo la información de usuario

Cookie Una cabecera muy importante para envío de información.From La dirección de email del cliente. Host El host y el puerto sacados de la URL original.If-Modified-Since Para indicar que solo han de enviarse

documentos posteriores al actual. Si no es así, se envía una respuesta 304 "Not Modified".

Pragma Si contiene el valor no-cache indica que el servidor ha de enviar una nueva copia del documento.

Referer La URL de la página que contenía el link que el cliente siguió para llegar a la pagina actual.

User-Agent El tipo de navegador que usa el cliente. Es útil si se va enviar contenido especifico para un tipo de navegador.

UA-Pixels, UA-Color, UA-OS, UA-CPU Cabeceras no estándar enviadas desde IE indicando el tamaño de pantalla, la profundidad de color, el SO y el tipo de cpu usado en el cliente.

Page 51: Tema servlets

Servlets: Recogiendo la información de usuario

Los métodos para acceder a estas cabeceras son: “getHeader” de “HttpServletRequest” que

devuelve un String. “getHeaderNames” de “HttpServletsRequest”

que devuelve un Enumeration de strings. Puede que algunos clientes recojan

información de un servlet. Para ello se puede hacer polimorfismo del método “getServletInfo” que debe devolver un String.

Revisar: examples\servlets\ej8_listheaders_servlet

Page 52: Tema servlets

Listando Cabeceras

http://localhost:8080/myapp/servlet/PruebaServlet

// compile: javac -classpath %TOMCAT_HOME%\common\lib\servlet-api.jar PruebaServlet.java

import javax.servlet.*;

import javax.servlet.http.*;

import java.io.*;

import java.util.*;

public class PruebaServlet extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

response.setContentType("text/html");

PrintWriter out = response.getWriter();

Enumeration enumeration = request.getHeaderNames();

while (enumeration.hasMoreElements()) {

String header = (String) enumeration.nextElement();

out.println(header + ": " + request.getHeader(header) + "<BR>");

}

}

}

Page 53: Tema servlets

Servlets: Políticas de acceso concurrente (threading)

Los servlets están diseñados para soportar múltiples accesos simultáneos por defecto.

El problema puede surgir cuando se hace uso de un recurso compartido.

Se exponen soluciones a poder considerar: Hacer que el servlet permita un único

acceso cada vez. Hacer que el recurso sea el que posea la

política de acceso concurrente.

Page 54: Tema servlets

Servlets: Políticas de acceso concurrente (threading)

Para hacer que el servlet trate a un cliente cada vez, únicamente hay que hacer que nuestra clase, además de heredar de “HttpServlet”, implemente la interfaz “SingleThreadModel” que es una interfaz sin métodos.

Page 55: Tema servlets

Servlets: Accediendo a variables CGI

Una colección de información derivada de muchos elementos que es accesible a través del objeto “HttpServletRequest” y el contexto del servlet.

Estas variables pueden ser proporcionadas por: La petición (la línea de petición o parte del

URI o las cabeceras). Del socket en sí (la IP). De los parámetros de instalación del

servidor web (los mapeos de las URL a los paths).

Page 56: Tema servlets

Servlets: Accediendo a variables CGI

AUTH_TYPE

El esquema especificado si se recibe una cabecera Authorization. Puede ser basic o digest.

request.getAuthType()

 CONTENT_LENGTH

Solo para peticiónes POST e indica el numero de bytes enviados.

String.valueOf(request.getContentLength()) o

request.getContentLength

 CONTENT_TYPE

El tipo de MIME.

request.getContentType()

 DOCUMENT_ROOT

La ruta el directorio http://host/

getServletContext().getRealPath("/")

 http_XXX_YYY

Acceso a librerías HTTP

request.getHeader("Xxx-Yyy")

Page 57: Tema servlets

Servlets: Accediendo a variables CGI

PATH_INFO

Información de path añadida a la petición. De todas formas no tiene por que ser tratada de manera independiente (no como en los CGIs).

request.getPathInfo()

PATH_TRANSLATED

Información de path de mapeo en el las rutas reales del servidor.

request.getPathTranslated()

QUERY_STRING

Para las peticiónes GET. Es un string aun codificado en URL. Mejor usar request.getParameter

request.getQueryString()

REMOTE_ADDR

La IP del cliente.

request.getRemoteAddr()

REMOTE_HOST

El nombre de dominio del cliente. Si no se puede devuelve la IP.

request.getRemoteHost()

Page 58: Tema servlets

Servlets: Accediendo a variables CGI

REMOTE_USER

La parte de usuario de una cabecera Authorization.

request.getRemoteUser()

REQUEST_METHOD

El tipo de petición: GET, POST, HEAD, PUT, DELETE, OPTIONS, o TRACE.

request.getMethod()

SCRIPT_NAME

El path al servlet

request.getServletPath()

SERVER_NAME

El nombre del servidor web

request.getServerName()

SERVER_PORT

El numero del puerto donde el servidor web esta “escuchando”.

Equivalente a String.valueOf(request.getServerPort()) Pero directamente…

request.getServerPort()

Page 59: Tema servlets

Servlets: Accediendo a variables CGI

SERVER_PROTOCOL

Nombre y versión usados en la línea de petición (e.i. HTTP/1.0 or HTTP/1.1).

request.getProtocol()

SERVER_SOFTWARE

Información de identificación del servidor web

getServletContext().getServerInfo()

Page 60: Tema servlets

Servlets: Respondiendo: Códigos de estado

La respuesta esta compuesta por: Una línea de estado (200 OK). Cabeceras de respuesta. Una línea en blanco. Un documento.

La línea de estado indica la versión del protocolo http y un código de estado para indicar diferente información al cliente: Enviar al usuario a otros enlaces. Indicar que el contenido es una imagen,

PDF... Requerir un password.

Page 61: Tema servlets

Servlets: Respondiendo: Códigos de estado

La línea de estado consta de: Versión del protocolo HTTP: La

suministra el servidor. El código de estado: Lo podemos indicar

nosotros. Usar el método “setStatus” de “HttpServletResponse”.

Un mensaje: Suele estar relacionado con el código de estado.

El código debe indicarse antes de cualquier acceso al PrintWriter.

Page 62: Tema servlets

Ejemplo HTTP Response

HTTP/1.1 200 OK Date: Thu, 06 Aug 1998 12:00:15 GMT Server: Apache/1.3.0 (Unix) Last-Modified: Mon, 22 Jun 1998 09:23:24 GMT

Content-Length: 6821 Connection: close Content-Type: text/html

Cuerpo de la respuesta ...

Page 63: Tema servlets

Servlets: Respondiendo: Códigos de estado

Aunque “setStatus” es la manera más flexible, hay unos códigos muy comunes y unos métodos para usarlos: “sendError” envía un mensaje de error

404. “sendRedirect” que se usa para enviar un

mensaje 302 conjuntamente con la cabecera de respuesta “Location” indicando la nueva URL.

Es importante conocer la versión de protocolo HTTP soportado con “getProtocol” de “HttpServletRequest”.

Page 64: Tema servlets

Servlets: Respondiendo: Códigos de estado

100

Continue

Continuar con la petición parcial. (HTTP 1.1)

101

Switching Protocols

El servidor debera responder con la cabecera Upgrade y asi cambiar de protocolo. (HTTP 1.1)

200

OK

Todo correcto. Por defecto en los servlets.

201

Created

El servidor ha creado un documento. En la cabecera Location se incluye la URL.

202

Accepted

La petición ha sido aceptada pero el procesamiento no ha terminado.

Page 65: Tema servlets

Servlets: Respondiendo: Códigos de estado

203

Non-Authoritative Information

El documento ha sido devuelto correctamente pero alguna cabecera es incorrecta (HTTP 1.1)

204

No Content

No hay nuevo documento. El cliente debe presentar el actual.

205

Reset Content

No hay nuevo documento pero el cliente debe refrescar el actual. Para resetear las variables CGI de los formularios (HTTP 1.1)

206

Partial Content

El cliente envio una petición parcial con una cabecera Range y el servidor la ha rellenado. (HTTP 1.1)

300

Multiple Choices

El documento que se ha solicitado se puede encontrar en múltiples sitios. La preferida o por defecto del servidor se ha de indicar en la cabecera Location.

Page 66: Tema servlets

Servlets: Respondiendo: Códigos de estado

301

Moved Permanently

El documento solicitado está en otro sitio. Se indica la URL en la cabecera Location. El navegador debería ir directamente.

302

Found

Similar a 301, pero la nueva URL debe entenderse como temporal. "Moved Temporarily" en HTTP 1.0, con la constante SC_MOVED_TEMPORARILY de HttpServletResponse, (no SC_FOUND). Tambien se puede usar el método directo response.sendRedirect(url).

303

See Other

Lo mismo que 301/302. (HTTP 1.1)

304

Not Modified

Cuando se determina que el cliente hace una petición condicional y se quiere indicar que el documento que actualmente posee es el correcto (e.i. como respuesta a una cabecera If-Modified-Since).

305

Use Proxy

El documento solicitado debería ser accedido por el proxy indicado en la cabecera Location. (HTTP 1.1)

Page 67: Tema servlets

Servlets: Respondiendo: Códigos de estado

307

Temporary Redirect

Identico a 302. No hay una variable en HttpServletResponse. (HTTP 1.1)

400

Bad Request

petición con sintaxis errónea.

401

Unauthorized

El cliente intento acceder a una pagina protegida con password sin la autorizacion necesaria. La respuesta incluye una cabecera WWW-Authenticate para que el cliente introduzca los datos en un dialogo que envia sus datos en la cabecera Authorization.

403

Forbidden

El recurso no esta disponible por un error en el servidor (permisos, acceso erroneo…).

404

Not Found

El recurso no pudo ser accedido. Posee un método propio HttpServletResponse: sendError(message).

Page 68: Tema servlets

Servlets: Respondiendo: Códigos de estado

405

Method Not Allowed

El método de petición (GET, POST, HEAD, DELETE, PUT, TRACE, etc.) no es permitido para el recurso solicitado. (HTTP 1.1)

406

Not Acceptable

Incompatibilidad de tipo MIME. (HTTP 1.1)

407

Proxy Authentication Required

Lo mismo que 401, pero se obliga a usar una cabecera Proxy-Authenticate por parte del servidor. (HTTP 1.1)

408

Request Timeout

El cliente tardo demasiado en enviar una petición. (HTTP 1.1)

409

Conflict

Generalmente en método PUT. Suele enviarse si se ha solicitado una versión incorrecta de un recurso. (HTTP 1.1)

Page 69: Tema servlets

Servlets: Respondiendo: Códigos de estado

410

Gone

El documento no esta disponible. La diferencia con 404 es que tiene carácter temporal. (HTTP 1.1)

411

Length Required

El servidor no puede procesar la petición si el usuario no envía una cabecera Content-Length. (HTTP 1.1)

412

Precondition Failed

Alguna precondición especificada en las cabeceras de petición era falsa. (HTTP 1.1)

413

Request Entity Too Large

El documento solicitado es mayor de lo que el servidor esta dispuesto a gestionar. Si el servidor estará dispuesto de gestionarlo mas tarde deberá incluir una cabecera de respuesta Retry-After. (HTTP 1.1)

414

Request URI Too Long

La URL es demasiado larga. (HTTP 1.1)

Page 70: Tema servlets

Servlets: Respondiendo: Códigos de estado

415

Unsupported Media Type

La petición esta en un formato desconocido. (HTTP 1.1)

416

Requested Range Not Satisfiable

El cliente introdujo una cabecera Range inadecuada en su petición. (HTTP 1.1)

417

Expectation Failed

El valor de la cabecera de petición Expect no se ha podido contrastar. (HTTP 1.1)

500

Internal Server Error

Un mensaje genérico para indicar que el servidor está confuso.

501

Not Implemented

El servidor no posee la funcionalidad para completar la petición. Por ejemplo si el usuario ha hecho una petición PUT que el servlet no es capaz de procesar.

502

Bad Gateway

Usado por servidores que funcionan como proxies o puertas de enlace para indicar que recibió una respuesta incorrecta por el servidor remoto.

Page 71: Tema servlets

Servlets: Respondiendo: Códigos de estado

503

Service Unavailable

El servidor no puede responder por mantenimiento o colapso de conexiones. Se puede enviar conjuntamente a una cabecera Retry-After.

504

Gateway Timeout

Usado por servidores que funcionan como proxies o puestas de enlace para indicar que no recibido respuesta del servidor remoto en un tiempo adecuado. (HTTP 1.1)

505

HTTP Version Not Supported

El servidor no es capaz de responder a la version del protocolo http indicado en la petición. (HTTP 1.1)

Page 72: Tema servlets

Servlets: Respondiendo: Cabeceras de respuesta

Un componente más en la línea de estado.

Íntimamente ligadas con los códigos de estado. Especificar cookies Suministrar la fecha de modificación (para

la caché) Instruir al navegador sobre la recarga de la

página después de un intervalo designado Decir cuanto tiempo va a estar el fichero

usando conexiones persistentes ...

Page 73: Tema servlets

Servlets: Respondiendo: Cabeceras de respuesta

El método más general para indicar una cabecera de respuesta es “setHeader” de “HttpServletResponse” y recibe 2 strings:

1. El nombre de la cabecera.2. El valor de la cabecera.

Antes de usar PrintWriter.

Page 74: Tema servlets

Servlets: Respondiendo: Cabeceras de respuesta

Existen 2 métodos para cabeceras relacionadas con: FECHAS: “setDateHeader” para ahorrar el

tener que pasar una fecha Java (Date) a milisegundos.

ENTEROS: “setIntHeader” para ahorrar el tener que pasar un entero a String.

Page 75: Tema servlets

Servlets: Respondiendo: Cabeceras de respuesta

Se puede consultar si una cabecera ya ha sido indicada en la respuesta mediante el método “containsHeader”.

Para añadir un valor a una cabecera que ya haya sido seleccionada, se usan los métodos “addHeader”, “addDateHeader” y “addIntHeader”.

Page 76: Tema servlets

Servlets: Respondiendo: Cabeceras de respuesta

"HttpServletResponse" también suministra unos métodos para especificar cabeceras comunes: "setContentType" selecciona la cabecera Content-Type.

"setContentLength" selecciona la cabecera Content-Length, útil si el navegador soporta conexiones HTTP persistentes (keep-alive).

"addCookie" selecciona un cookie (no existe el correspondiente setCookie, ya que es normal que haya varias líneas Set-Cookie).

"sendRedirect" selecciona la cabecera Location y el código de estado 302.

Page 77: Tema servlets

Servlets: Respondiendo: Cabeceras de respuesta

Allow

Indica los métodos que soporta el servidor

Content-Encoding

Indica el método usado para codificar el documento. El usar compresión puede reducir el tamaño de los documentos pero antes es mejor asegurarse que la compresión esta soportada usando la cabecera Accept-Encoding (e.i. request.getHeader("Accept-Encoding")).

Content-Length

Indica el numero de bytes que se están enviando. Solo es necesaria si se están usando conexiones http persistentes (sep-alive). Lo mas sencillo es escribir en un ByteArrayOutputStream, luego ver el tamaño e indicarlo en Content-Length y al final enviarlo con byteArrayStream.writeTo(response.getOutputStream()).

Content-Type

Indica el tipo de codificación MIME del documento. Por defecto es text/plain, por lo que se suele indicar text/html. Existe un método para ello en HttpServletResponse que es setContentType.

Date

Indica la hora actual. Hay que usar el método setDateHeader.

Page 78: Tema servlets

Servlets: Respondiendo: Cabeceras de respuesta

Expires

Indica el tiempo en el que el contenido debe considerarse no valido y por lo tanto no introducirlo en la cache.

Last-Modified

Indica cuándo cambio el documento por última vez. El cliente puede preguntar por ello usando la cabecera de petición If-Modified-Since que se trata como una GET condicional y se responde con Last-Modified si la fecha es posterior. En otro caso se envia 304 (Not Modified) como estado. Usar setDateHeader.

Location

Indica la URL donde el cliente debe ir. Se suele usar con el estado 302 y el método sendRedirect de HttpServletResponse.

Server

Indica el tipo de servidor. No lo suele indicar el servlet sino el propio servidor web.

Set-Cookie

Indica la cookie asociada a la página. Es recomendable no usar response.setHeader("Set-Cookie", ...), y en su defecto addCookie de HttpServletResponse.

Page 79: Tema servlets

Servlets: Respondiendo: Cabeceras de respuesta

Refresh

Indica cuándo debería pedir el navegador una página actualizada. En lugar de recargar la página actual, podemos especificar otra página a cargar mediante setHeader("Refresh", "5; URL=http://host/path"). Se suele seleccionar mediante la cabecera HTML <META HTTP-EQUIV="Refresh" CONTENT="5; URL=http://host/path"> en la sección HEAD, mejor que una cabecera explícita desde el servidor. Esto es porque la recarga o el reenvio automático es algo deseado por los autores de HTML que no tienen accesos a CGI o servlets. Pero esta cabecera significa "Recarga esta página o ve a URL especificada en n segundos" y no significa "recarga esta página o ve la URL especificada cada n segundos". Por eso tenemos que enviar una cabecera Refresh cada vez. De todas formas no es una cabecera oficial del HTTP 1.1, pero es una extensión soportada por Netspace e Internet Explorer

WWW-Authenticate

Indica el tipo de autorización y dominio que debería suministrar el cliente en su cabecera Authorization. Esta cabecera es necesaria en respuestas que tienen una línea de estado 401 (Unauthorized). (e.i. response.setHeader("WWW-Authenticate", "BASIC realm=\"executives\"")).

Page 80: Tema servlets

Servlets: Acceso a recursos ACCEDER A RECURSOS DEL SERVIDOR

Posibilidades:1. Hacer que el servlet haga una petición HTTP.2. Pedir el recurso mediante el

"RequestDispatcher". Para acceder al RequestDispatcher hay

que recoger el contexto del servlet mediante el método “getServletContext”.

Page 81: Tema servlets

Servlets: Acceso a recursos

Seguidamente debemos acceder al recurso:ServletContext sc = getServletContext();

RequestDispatcher rd = sc.getRequestDispatcher(“/pagina.html");

Una vez tenemos el recurso accesible podemos: Hacer que el recurso sea el encargado de dar

la respuesta a la petición. Usamos el método “forward” por lo que no podemos responder nosotros.

Hacer una respuesta conjunta a la petición entre el recurso y nuestro servlet usando el método “include”

Page 82: Tema servlets

Servlets: Acceso a recursos En otra ocasiones puede que se

quiera compartir recursos entre distintos servlets.

Hacer uso de los atributos del “ServletContext”.

Útil para servlets del mismo servidor y sobre todo para servlets de la misma aplicación.

Page 83: Tema servlets

Servlets: Acceso a recursos CONVENCIÓN PARA NOMBRES DE

ATRIBUTOS: Se suele usar la misma nomenclatura usada para los paquetes para evitar conflictos. Añadir un atributo: Se usa el método

“setAttribute” de “ServletContext”. Esto se suele hacer en la inicialización del servlet. El control de que varios servlets manejen un mismo atributo es responsabilidad del desarrollador.

Recoger un atributo: Se usa el método “getAttribute” de “ServletContext”. Hay que convertir el objeto que devuelve al tipo requerido.

Page 84: Tema servlets

Servlets: Acceso a recursos Eliminar un atributo: Se puede eliminar un

atributo del contexto usando el método “removeAttribute” de “ServletContext”.

Page 85: Tema servlets

Reenviando Respuestas

Es posible delegar el procesamiento de un servlet a otro mediante la clase javax.servlet.RequestDispatcher

Define dos métodos: include sirve para incluir contenido de

otro recurso forward para enviar una petición de un

servlet a otro Difiere de HttpServetResponse.sendRedirect(),

que redirige la petición con la ayuda del navegador

Page 86: Tema servlets

Reenviando Respuestas

Para obtener un objeto RequestDispatcher: A partir del método getRequestDispatcher

o getNamedDispatcher de javax.servlet.ServletContext path recibido relativo al directorio raíz del servidor o nombre del recurso

El método getRequestDispatcher de javax.servlet.ServletRequest recibe un path como parámetro relativo a la petición actual HTTP

Page 87: Tema servlets

Reenviando Respuestas

// Revisar: examples\servlets\ej10_include_servlet

RequestDispatcher rd = request.getRequestDispatcher("/servlet/SecondServlet?name=diego");

rd.include(request, response);

// Revisar: examples\servlets\ej11_forward_servlet

RequestDispatcher rd = request.getRequestDispatcher("SecondServlet");

rd.forward(request, response);

Page 88: Tema servlets

Gestión de Sesiones

HTTP no tiene estado Necesario utilizar trucos para

permitirlo: Reescritura de urls Campos hidden <input type=“hidden” name=“saludo” value=“hola”>

Cookies HttpSession

Page 89: Tema servlets

Servlets: Respondiendo: Cookies

Pequeños trozos de información textual que el servidor puede enviar al cliente y que éste no modifica y reenvía al servidor cuando vuelve a visitar el mismo sitio.   Identificar a un usuario concreto. Para sitios con baja necesidad de seguridad,

poder evitar el login y password. Personalizar las webs recordando cada

peculiaridad de cliente. Publicidad enfocada (personalizada) dado

que se puede almacenar información sobre las preferencias del usuario mientras navega, busca información etc.

Page 90: Tema servlets

Servlets: Respondiendo: Cookies

Las cookies no son un grave problema de seguridad.

Los navegadores sólo permiten 20 cookies por sitio web y 300 en total.

Limitadas a 4kb. Pueden ser un problema de privacidad.

Puede que algunos usuarios desactiven las cookies por diversas razones por lo que no se recomienda depender completamente del uso de ellas.

Page 91: Tema servlets

Servlets: Respondiendo: Cookies

Para utilizar cookies lo único que hay que hacer es:

1) Crear una cookie: “new Cookie(String name, String value)” El nombre no puede contener ni espacios ni: [ ] ( ) = , " / ? @ : ;  

2) Especificar algún atributo a la cookies mediante alguno de sus métodos: getComment/setComment: Comentarios

asociados a la cookie.

Page 92: Tema servlets

Servlets: Respondiendo: Cookies

getDomain/setDomain: Indicar el dominio al que se aplica la cookie. Por defecto la cookie se devuelve a la misma dirección que la envió, pero así podemos indicar que se reenvíe a otros servidores en el mismo dominio. El dominio debe empezar por un ‘.’

getMaxAge/setMaxAge: Indicar el tiempo que debe pasar en segundos hasta que la cookie expire. Si no se indica la cookie dura una sesión.

Page 93: Tema servlets

Servlets: Respondiendo: Cookies

getName/setName: Indicar el nombre de la cookie.

getPath/setPath: Indica a que rutas responde la cookie. Si no se indica nada, la cookie se envía para cualquier página en el mismo path actual. Se podría usar para usos generales como someCookie.setPath("/"). Hay que incluir al menos el directorio actual.

getSecure/setSecure: Sólo vale para sesiones seguras (e.i. SSL).

Page 94: Tema servlets

Servlet: Respondiendo: Cookies

getValue/setValue: Indicar el valor de la cookie.

getVersion/setVersion: Indicar con que version del protocolo funciona esta cookie.

3) Añadir la cookie a la respuesta: “response.addCookie(Cookie)”

Page 95: Tema servlets

Servlets: Respondiendo: Cookies

Para acceder a las cookies que el cliente reenvía cada vez que accede al recurso se usa el método “getCookies” de “HttpServletRequest” que devuelve un array de cookies.

Con los métodos “getName” y “getValue” de “Cookie” se accede a la información de la cookie.

Page 96: Tema servlets

Servlets: Seguimiento de sesión

El protocolo HTTP no posee la capacidad de almacenar estados.

Se complican mucho las tareas de guardar las acciones (e.i. Compras) de un usuario.

3 posibles soluciones: Cookies. Añadir información en la URL Usar campos ocultos de formularios (HIDDEN)

Revisar: examples\servlets\ej12_cookie_servlet

Page 97: Tema servlets

Servlets: Seguimiento de sesión

Los servlets proporcionan una solución técnica: La API HttpSession.

Una interfaz de alto nivel construida sobre los cookies y la reescritura de las urls (pero transparente para el desarrollador).

Permite almacenar objetos.

Page 98: Tema servlets

Servlets: Seguimiento de sesión Pasos para trabajar con sesiones:

BUSCAR EL OBJETO HttpSession ASOCIADO A UNA PETICIÓN: Se usa el método “getSession” de “HttpServletRequest” que devuelve null si no hay una sesión asociada. Entonces podríamos crear una pero al ser una tarea sumamente común, se pasa true y él mismo se encarga de crear una.

Page 99: Tema servlets

Servlets: Seguimiento de sesión

BUSCAR INFORMACION ASOCIADA A LA SESION: Usar los métodos “getValue” (o “getAttribute” para versiones del API Servlet 2.2+) que devuelve un Object o null. Para asignar un valor dentro de una sesión se usa el método “putValue” (o “setAttribute” para versiones del API Servlet 2.2+). Para conocer los nombres de los valores están los métodos “getValueNames” (o “getAttributeNames para versiones del API Servlet 2.2+) que devuelve un Enumeration.

Existen otros métodos que aportan información sobre la sesión.

Page 100: Tema servlets

Servlets: Seguimiento de sesióngetId. 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 una 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.

Page 101: Tema servlets

Servlets: Seguimiento de sesión

AÑADIR INFORMACION A UNA SESION: Los métodos “putValue” y “setAttribute” eliminan (machacan) el valor anterior del atributo por lo que para añadir información hay que recuperar el valor primero y después de modificarlo, volver a pasarlo a la sesión.

INVALIDAR UNA SESION: Automáticamente el servidor web invalida tras un periodo de tiempo (30’) sin peticiones o manualmente usando el método “invalidate”.

Revisar: examples\servlets\ej13_session_servlet

Page 102: Tema servlets

JDBC de Javasoft: arquitectura I

Aplicac iónJava

Aplicac iónJava

API JD BC

D river API

JD BC -O D BCT ipo 1

API N ativoParte en Java

T ipo 2

D river de R eden Java Puro

T ipo 3

G estor deD river O D BC

D river O D BC

P ro toco loS G B DN ativo

P ro toco loS G B DN ativo

Servidor

P ro toco lode R ed

P rop ie ta rio

D river deSG BD N ativo

P ro toco loS G B DN ativo

P ro toco loS G B DN ativo

G estor de D rivers

D river deSG BD N ativo

P rotoco loN ativo

D river en JavaT ipo 4

Page 103: Tema servlets

JDBC de Javasoft: arquitectura II Gestor de drivers es núcleo de

arquitectura y comunica aplicaciones Java con cuatro tipos diferentes de drivers: Puente ODBC-JDBC más el driver ODBC

Traduce JDBC en ODBC No adecuado si parte cliente es anónima

Necesidad de registrar fuente ODBC en cada máquina Uso: aplicaciones de dos capas en red local

Page 104: Tema servlets

JDBC de Javasoft: arquitectura III

API Nativo parte en Java: Traduce JDBC en protocolo específico de BD: Oracle

JDBC/OCI driver Requieren algo de código nativo en cada máquina

cliente en forma de un driver específico que se debe instalar

Uso: servidores RMI, servlets Driver de Red en Java Puro:

Utiliza protocolo comunicaciones publicado para la comunicación con un servidor remoto

Servidor se comunica con la BD utilizando ODBC o un driver nativo

Java puro: applets se descarga lo mínimo No requiere código instalado en máquina cliente

Page 105: Tema servlets

JDBC de Javasoft: arquitectura IV

Protocolo nativo en Java Puro: Implementan protocolo de BD de un

suministrador Específicos para BD concreta No tienen necesidad de intermediarios Alto rendimiento

Page 106: Tema servlets

JDBC URLs

URL: esquema de nombres para localizar BD

Sintaxis: jdbc:<subprotocolo>:<subnombre> jdbc:odbc:cliente jdbc:msql://www.deusto.es:1112/catalogo

jdbc:mysql://localhost:3306/docman

Page 107: Tema servlets

Correspondencia tipos SQL/Java

Tipo SQL Tipo Java Descripción

CHAR string Un carácter

VARCHAR string Cadena de caracteres de longitud variable

NUMERIC java.math.BigDecimal

Valor numérico para cantidades económicas

BIT boolean Valor binario (0 o 1)

INTEGER int Entero de 32 bits con signo

REAL float Valor en punto flotante

DATE java.sql.Date Formato Fecha ‘aaaa-mm-dd’

TIME java.sql.Time Formato Hora ‘hh-mm-ss’

Page 108: Tema servlets

JDBC API: java.sql.* I

Carga de un driver Crea instancia de si mismo Se registra con el gestorString myDriver =

“sun.jdbc.odbc.JdbcOdbcDriver”;Class.forName(myDriver);

Conexión a la BD:String url = “jdbc:odbc:clientes”;String user = “dba”;String pass = “sql”;Connection dbCon =

DriverManager.getConnection(url, user, pass);

Page 109: Tema servlets

JDBC API: java.sql.* II

Ejecución de sentencias SQLStatement stmt = dbCon.createStatement();

3 posibilidades: executeQuery() 1 conjunto de resultadosResultSet res = stmt.executeQuery(“select * from

compradores where prio=1”); executeUpdate()

DML (insert, update, deletee) nº filas afectadas DDL (create table) 0

int total = stmt.executeUpdate(“insert into prioridad (cod-pri, descripcion) values (4, ‘crítica’)”);

execute () Cuando no se sabe que va a devolver ResultSet

o nº

Page 110: Tema servlets

JDBC API: java.sql.* III

Otras posibilidades: PreparedStatement, se genera el plan de

acceso la primera vez que se solicita la ejecuciónPreparedStatement ps =

dbCon.prepareStatement(“sqlString”); CallableStatement procedimientos

almacenados Acceso al esquema o metadatos Control transaccional superficial

Defecto automático (1 SQL 1 commit) Deshabilitar (N SQL 1 commit o rollback)dbCon.setAutoCommit(false);…dbCon.commit();

Page 111: Tema servlets

Un ejemplo JDBC

import java.sql.*;…Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");String url = "jdbc:odbc:CuentasBD"; con = DriverManager.getConnection(url, "", "");stmt = con.createStatement();Vector cuentas = new Vector();String sql = "select * from CUENTAS order by

numeroCTA";ResultSet rs = stmt.executeQuery(sql);while (rs.next()) { cuentas.add(new CuentaBancaria(rs.getString("numeroCTA"), rs.getDate("fechaExpiracion"), rs.getFloat("saldo")));}stmt.close();con.close();

Page 112: Tema servlets

SQL Inmerso (Embedded SQL – ESQL) ESTÁTICO

El lenguaje de programación junto con el cual se utiliza SQL se denomina lenguaje anfitrión

Objetivo: insertar sentencias SQL en aplicaciones codificadas en cualquier lenguaje: C, C++, COBOL, FORTRAN, Pascal, ADA y Java Identificadores especiales para cada lenguaje, se

usan para separar las instrucciones de SQL inmerso y el código del lenguaje anfitrión: Java SQLJ:

# sql {insert into Pedidos values(:p1 :p2}; C PRO*C:

EXEC SQL DECLARE stu_cursor CURSOR FOR SELECT * FROM STUDENT ORDER BY NAME;

Precompilador genera código en lenguaje apropiado a partir de las sentencias SQL incrustadas

Page 113: Tema servlets

SQL Embebido (Embedded SQL – ESQL) (cont)

Ventajas: Verificación de sintaxis en tiempo de

compilación mayor eficiciencia Desventajas:

BD debe ser conocida y su esquema accesible en tiempo de compilación

Precompiladores no estándar y propietario para cada BD

Page 114: Tema servlets

SQLJ vs. JDBCString vName; int vSalary; String vJob; Java.sql.Timestamp vDate; ... ESTÁTICO SQLJ#sql { SELECT Ename, Sal INTO :vName, :vSalary FROM Emp WHERE Job = :vJob and HireDate = :vDate }; String vName; int vSalary; String vJob; Java.sql.Timestamp vDate; ... DINÁMICO JDBCPreparedStatement stmt = connection.prepareStatement( "SELECT Ename, Sal " + "FROM Emp " + "WHERE Job =? and HireDate = ?"); stmt.setString(1, vJob); stmt.setTimestamp(2, vDate); ResultSet rs = stmt.executeQuery(); rs.next(); vName = rs.getString(1); vSalary = rs.getInt(2); rs.close();

Page 115: Tema servlets

Servlet con JDBC

// examples\servlets\ej14-db_servlet

public class RegistrationServlet extends HttpServlet {

private String firstName = "";

private String lastName = "";

private String userName = "";

private String password = "";

public void init() {

try {

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

System.out.println("JDBC driver loaded");

}

catch (ClassNotFoundException e) {

System.out.println(e.toString());

}

}

Page 116: Tema servlets

Servlet con JDBC

public void doPost(HttpServletRequest request,

HttpServletResponse response)

throws ServletException, IOException {

sendPageHeader(response);

firstName = request.getParameter("firstName");

lastName = request.getParameter("lastName");

userName = request.getParameter("userName");

password = request.getParameter("password");

boolean error = false;

String message = null;

try {

Connection con = DriverManager.getConnection("jdbc:odbc:UsersDB");

System.out.println("got connection: " + password);

Statement s = con.createStatement();

String sql = "SELECT UserName FROM Users" +

" WHERE userName='" + StringUtil.fixSqlFieldValue(userName) + "'";

ResultSet rs = s.executeQuery(sql);

System.out.println("Ejecutando select: ");

if (rs.next()) {

rs.close();

message = "The user name <B>" + StringUtil.encodeHtmlTag(userName) +

"</B> has been taken. Please select another name.";

System.out.println(message);

error = true;

}

// ...

}

Page 117: Tema servlets

Servlet Filters

Un filtro te da acceso a los objetos HttpServletRequest y HttpServletResponse antes y después, respectivamente, de que lleguen a un recurso web.

Los filtros se declaran en el web.xml con el elemento xml <filter> y su uso se indica mediante <filter-mapping> Se puede asociar un filtro a un patrón de url Además los filtros se pueden encadenar

Definidos por los interfaces: Filter, FilterConfig y FilterChain

Revisar: examples\servlets\ej15_filter_servlet

Page 118: Tema servlets

Ejemplo Filter

// compile: javac -classpath %TOMCAT_HOME%\common\lib\servlet-api.jar;. UpperCaseFilter.java

import java.io.*;import javax.servlet.Filter;import javax.servlet.FilterChain;import javax.servlet.FilterConfig;import javax.servlet.ServletContext;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import java.util.Enumeration;

public class UpperCaseFilter implements Filter { private FilterConfig filterConfig = null; public void destroy() { System.out.println("Filter destroyed"); this.filterConfig = null; }

Page 119: Tema servlets

Ejemplo Filter

public void doFilter(ServletRequest request, ServletResponse response,

FilterChain chain) throws IOException, ServletException { System.out.println("Filter"); Enumeration enum = request.getAttributeNames(); while (enum.hasMoreElements()) { String attributeName = (String) enum.nextElement(); String attributeValue = (String)

request.getAttribute(attributeName); request.setAttribute(attributeName,

attributeValue.toUpperCase()); } chain.doFilter(request, response); } public void init(FilterConfig filterConfig) throws ServletException

{ System.out.println("Filter initialized"); this.filterConfig = filterConfig; }}

Page 120: Tema servlets

Web.xml

<web-app>

<filter>

<filter-name>

Trim Filter

</filter-name>

<filter-class>

TrimFilter

</filter-class>

</filter>

<filter-mapping>

<filter-name>

Trim Filter

</filter-name>

<servlet-name>

DoublyFilteredServlet

</servlet-name>

</filter-mapping>

<servlet>

<servlet-name>

DoublyFilteredServlet

</servlet-name>

<servlet-class>

DoublyFilteredServlet

</servlet-class>

</servlet>

<servlet-mapping>

<servlet-name>DoublyFilteredServlet</servlet-name>

<url-pattern>/servlet/DoublyFilteredServlet</url-pattern>

</servlet-mapping>

</web-app>

Page 121: Tema servlets

Servlet

Son flexibles y muy potentes Sin embargo, es muy lioso mezclar

código de marcado y código Java A menudo hay más código de marcado

que código Java SOLUCIÓN JSP