Title: Tema 1- Servlets
1Tema 1- Servlets
- Dr. Diego Lz. de Ipiña Gz. de Artaza
- http//paginaspersonales.deusto.es/dipina
- http//paginaspersonales.deusto.es/dipina/cursos/J
2EECesine.zip - dipina_at_eside.deusto.es
2Introducció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
3HTTP
- Especificación de HTTP http//www.w3.org/Protocol
s/rfc2616/rfc2616.html - Básicamente debemos saber que los comandos
principales son HTTP GET y POST.
4Tecnología Servlet
- Piedra angular del desarrollo de aplicaciones web
en Java - Los JSPs son de hecho servlets disfrazados
5Caracterí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)
6Ventajas
- 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
7Arquitectura
- Servlet Container servidor web capaz de
ejecutar servlets - En una aplicación JSP, el contenedor se
corresponde a un JSP container.
8Funcionamiento de un Servlet
9Contenedor 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 ...
10Instalando Tomcat 5
- Requisitos
- Haber instalado Java 5
- Extraer fichero downloads\Tomcat5.5\jakarta-tomca
t-5.5.7.zip - Crear las siguientes variables de entorno, por
medio de Panel de Control-gtSistema-gtAvanzado-gtVari
ables de Entorno - TOMCAT_HOMEltTOMCAT_INSTALL_DIRgt
116 Pasos Para Crear tu Primer Servlet
- Crear una estructura de directorios bajo Tomcat
para tu aplicación - Escribir el código del servlet
- Compilar el código
- Crear un descriptor de explotación (deployment
descriptor) - Ejecutar Tomcat
- Invocar el servlet desde un navegador
12Crear 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
- Crear un directorio bajo webapps con el nombre de
tu aplicación myapp, que aparecerá en la url a
tu aplicación - 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
13Escribir 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("lthtmlgt")
- out.println("ltheadgt")
- String title rb.getString("helloworld.title
")
14Compilar el Código
- Guardar el código en TOMCAT_HOME\webapps\myapp\W
EB-INF\classes - Compilar el código
- javac classpath TOMCAT_HOME\common\lib\servlet-
api.jar HelloWorldExample.java
15Crear 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 ltweb-appgt - Se pueden encontra n elementos ltservletgt que
cuelgan de él
16Crear el web.xml
- lt?xml version"1.0" encoding"ISO-8859-1"?gt
- lt!DOCTYPE web-app
- PUBLIC "-//Sun Microsystems, Inc.//DTD Web
Application 2.3//EN" - "http//java.sun.com/dtd/web-app_2_3.dtd"gt
- ltweb-appgt
- ltdisplay-namegtServlet 2.4 Exampleslt/display-na
megt - ltdescriptiongt
- Servlet 2.4 Examples.
- lt/descriptiongt
-
- ltservletgt
- ltservlet-namegtHelloWorldExamplelt/servlet-n
amegt - ltservlet-classgtHelloWorldExamplelt/servlet-
classgt - lt/servletgt
-
-
- ltservlet-mappinggt
- ltservlet-namegtHelloWorldExamplelt/servlet-n
amegt
17Ejecutar el Código
- Arrancar Tomcat si es necesario, mediante el
comando TOMCAT_HOME\bin\catalina.bat run - Invocar al servlet http//localhost8080/myapp/He
lloWorldExample
18Resultado de Ejecutar Servlet
19Servlets Jerarquía
- La jerarquía de clases java es...
- Únicamente hay que hacer polimorfismo de los
métodos que se quieran tratar.
20Las APIs
- Dos paquetes permiten la programación de
servlets - javax.servlet
- javax.servlet.http
- Revisar documentación
- Arrancar Tomcat
- Visitar http//localhost8080
21Servlets Ciclo de vida
- Ciclo de vida de un servlet
22Servlets 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
23Demostrando 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
24Servlets 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.
25Servlets 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.
26Servlets Operaciones duraderas
- Posible solución Contador
- public 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)
27Servlets 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() gt 0)
- setShuttingDown(true)
-
- while(numServices() gt 0)
- try wait()
- catch (InterruptedException e)
-
-
28Recuperando Configuración
- Recuperando información de configuración del
fichero web.xml -
- ltservletgt
- ltservlet-namegtConfigDemoServletExamplelt/se
rvlet-namegt - ltservlet-classgtConfigDemoServletlt/servlet-
classgt - ltinit-paramgt
- ltparam-namegtadminEmaillt/param-namegt
- ltparam-valuegtdipina_at_ilargi.orglt/param-val
uegt - lt/init-paramgt
- ltinit-paramgt
- ltparam-namegtadminContactNumberlt/param-nam
egt - ltparam-valuegt6542214213lt/param-valuegt
- lt/init-paramgt
- lt/servletgt
29Recuperando 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.getInitParameter
Names() - while (parameters.hasMoreElements())
- String parameter (String) parameters.nextElem
ent() - System.out.println("Parameter name "
parameter) - System.out.println("Parameter value "
config.getInitParameter(parameter)) -
-
-
- // ...
-
30Contexto 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
31Contexto 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.getAtt
ributeNames() - 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())
32Petició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_serv
let
33Ejemplo ServletRequest y ServletResponse
- public void service(ServletRequest request,
ServletResponse response) - throws ServletException, IOException
-
- PrintWriter out response.getWriter()
- out.println("ltHTMLgt")
- // ...
- out.println("ltBRgtServer Port "
request.getServerPort()) - out.println("ltBRgtServer Name "
request.getServerName()) - out.println("ltBRgtProtocol "
request.getProtocol()) - out.println("ltBRgtCharacter Encoding "
request.getCharacterEncoding()) - out.println("ltBRgtContent Type "
request.getContentType()) - out.println("ltBRgtContent Length "
request.getContentLength()) - out.println("ltBRgtRemote Address "
request.getRemoteAddr()) - out.println("ltBRgtRemote Host "
request.getRemoteHost()) - out.println("ltBRgtScheme "
request.getScheme()) - Enumeration parameters request.getParameterN
ames() - while (parameters.hasMoreElements())
- String parameterName (String)
parameters.nextElement() - out.println("ltbrgtParameter Name "
parameterName)
34Clase 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
35Ejemplo 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("ltHTMLgt")
- out.println("ltHEADgt")
- out.println("ltTITLEgt")
- out.println("Extending GenericServlet")
- out.println("lt/TITLEgt")
- out.println("lt/HEADgt")
- out.println("ltBODYgt")
- out.println("Extending GenericServlet makes
your code simpler.") - out.println("lt/BODYgt")
36Paquete 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
37HttpServlet
- 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
38Servlets 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.1
- Accept 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,euq0.7,en-gbq0.3
- Accept-Encoding gzip, deflate
- User-Agent Mozilla/4.0 (compatible MSIE 6.0
Windows NT 5.1 .NET CLR 1.1.4322) - Host localhost9999
- Connection Keep-Alive
39Servlets 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.1
- Accept 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//localhost9999/search.html
- Accept-Language es,euq0.7,en-gbq0.3
- Content-Type application/x-www-form-urlencoded
- Accept-Encoding gzip, deflate
- User-Agent Mozilla/4.0 (compatible MSIE 6.0
Windows NT 5.1 .NET CLR 1.1.4322) - Host localhost9999
- Content-Length 13
- Connection Keep-Alive
- Cache-Control no-cache
- keyworddiego
40Servlets 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.
41Servlets 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
42Ejemplo 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("ltHTMLgt")
- out.println("ltHEADgt")
- out.println("ltTITLEgtThe GET methodlt/TITLEgt")
- out.println("lt/HEADgt")
- out.println("ltBODYgt")
- out.println("The servlet has received a GET.
" - "Now, click the button below.")
- out.println("ltBRgt")
43Ejemplo doGet() y doPost()
- public void doPost(
- HttpServletRequest request,
HttpServletResponse response) - throws ServletException, IOException
- response.setContentType("text/html")
- PrintWriter out response.getWriter()
- out.println("ltHTMLgt")
- out.println("ltHEADgt")
- out.println("ltTITLEgtThe POST
methodlt/TITLEgt") - out.println("lt/HEADgt")
- out.println("ltBODYgt")
- out.println("The servlet has received a POST.
Thank you.") - out.println("lt/BODYgt")
- out.println("lt/HTMLgt")
-
-
44Servlets 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).
45Servlets 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
46Listando 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("ltHTMLgt")
- out.println("ltHEADgt")
- out.println("ltTITLEgtObtaining the
Parameterlt/TITLEgt") - out.println("lt/HEADgt")
- out.println("ltBODYgt")
- out.println("The request's parameters
areltBRgt")
47Listando Parámetros Recibidos
- Enumeration enumeration request.getParameter
Names() - while (enumeration.hasMoreElements())
- String parameterName (String)
enumeration.nextElement() - out.println(parameterName " "
- request.getParameter(parameterName)
"ltBRgt" ) -
- out.println("ltFORM METHODGETgt")
- out.println("ltBRgtFirst Name ltINPUT TYPETEXT
NAMEFirstNamegt") - out.println("ltBRgtLast Name ltINPUT TYPETEXT
NAMELastNamegt") - out.println("ltBRgtltINPUT TYPESUBMIT
VALUESubmitgt") - out.println("lt/FORMgt")
- out.println("lt/BODYgt")
- out.println("lt/HTMLgt")
-
-
48Servlets 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.
49Servlets 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.
50Servlets 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.
51Servlets 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
52Listando Cabeceras
- http//localhost8080/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.getHeaderNam
es() - while (enumeration.hasMoreElements())
- String header (String) enumeration.nextEle
ment() - out.println(header " "
request.getHeader(header) "ltBRgt") -
53Servlets 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.
54Servlets 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.
55Servlets 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).
56Servlets 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")
57Servlets 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()
58Servlets 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.getServerPor
t()) Pero directamente - request.getServerPort()
59Servlets 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()
60Servlets 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.
61Servlets 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.
62Ejemplo HTTP Response
- HTTP/1.1 200 OK
- Date Thu, 06 Aug 1998 120015 GMT
- Server Apache/1.3.0 (Unix)
- Last-Modified Mon, 22 Jun 1998 092324 GMT
- Content-Length 6821
- Connection close
- Content-Type text/html
- Cuerpo de la respuesta ...
63Servlets 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.
64Servlets 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.
65Servlets 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.
66Servlets 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)
67Servlets 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).
68Servlets 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)
69Servlets 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)
70Servlets 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.
71Servlets 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)
72Servlets 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 - ...
73Servlets Respondiendo Cabeceras de respuesta
- El método más general para indicar una cabecera
de respuesta es setHeader de HttpServletRespons
e y recibe 2 strings - El nombre de la cabecera.
- El valor de la cabecera.
- Antes de usar PrintWriter.
74Servlets 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.
75Servlets 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.
76Servlets 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.
77Servlets 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(respons
e.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.
78Servlets 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-Cooki
e", ...), y en su defecto addCookie de
HttpServletResponse.
79Servlets 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
URLhttp//host/path"). Se suele seleccionar
mediante la cabecera HTML ltMETA
HTTP-EQUIV"Refresh" CONTENT"5
URLhttp//host/path"gt 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-Auth
enticate", "BASIC realm\"executives\"")).
80Servlets Acceso a recursos
- ACCEDER A RECURSOS DEL SERVIDOR
- Posibilidades
- Hacer que el servlet haga una petición HTTP.
- Pedir el recurso mediante el "RequestDispatcher".
- Para acceder al RequestDispatcher hay que recoger
el contexto del servlet mediante el método
getServletContext.
81Servlets 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
82Servlets 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.
83Servlets 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.
84Servlets Acceso a recursos
- Eliminar un atributo Se puede eliminar un
atributo del contexto usando el método
removeAttribute de ServletContext.
85Reenviando Respuestas
- Es posible delegar el procesamiento de un servlet
a otro mediante la clase javax.servlet.RequestDisp
atcher - 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
86Reenviando 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
87Reenviando Respuestas
- // Revisar examples\servlets\ej10_include_servlet
- RequestDispatcher rd request.getRequestDispatche
r("/servlet/SecondServlet?namediego") - rd.include(request, response)
- // Revisar examples\servlets\ej11_forward_servlet
- RequestDispatcher rd request.getRequestDispatche
r("SecondServlet") - rd.forward(request, response)
88Gestión de Sesiones
- HTTP no tiene estado
- Necesario utilizar trucos para permitirlo
- Reescritura de urls
- Campos hidden ltinput typehidden namesaludo
valueholagt - Cookies
- HttpSession
89Servlets 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.
90Servlets 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.
91Servlets 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
( ) , " / ? _at_ - 2) Especificar algún atributo a la cookies
mediante alguno de sus métodos - getComment/setComment Comentarios asociados a la
cookie.
92Servlets 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.
93Servlets 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).
94Servlet 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)
95Servlets 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.
96Servlets 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
97Servlets 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.
98Servlets 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.
99Servlets 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.
100Servlets Seguimiento de sesión
- getId. Este método devuelve un identificador
único generado para cada sesión. Algunas veces es
usado como el nombre clave cuando hay un sólo
valor asociado con una sesión, o cuando se uso la
información de logging en sesiones anteriores. - isNew. Esto devuelve true si el cliente
(navegador) nunca ha visto la sesión, normalmente
porque acaba de ser creada en vez de empezar una
referencia a 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.
101Servlets 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
102JDBC de Javasoft arquitectura I
103JDBC 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
104JDBC 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
105JDBC 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
106JDBC URLs
- URL esquema de nombres para localizar BD
- Sintaxis
- jdbcltsubprotocologtltsubnombregt
- jdbcodbccliente
- jdbcmsql//www.deusto.es1112/catalogo
- jdbcmysql//localhost3306/docman
107Correspondencia 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
108JDBC API java.sql. I
- Carga de un driver
- Crea instancia de si mismo
- Se registra con el gestor
- String myDriver sun.jdbc.odbc.JdbcOdbcDriver
- Class.forName(myDriver)
- Conexión a la BD
- String url jdbcodbcclientes
- String user dba
- String pass sql
- Connection dbCon DriverManager.getConnection(url
, user, pass)
109J