Escolar Documentos
Profissional Documentos
Cultura Documentos
Introduccin
Necesidad de mecanismos para desarrollar aplicaciones web contenido dinmico Cuando escribes una URL en tu navegador:
El navegador establece una conexin TCP/IP con el
servidor El navegador enva una peticin al servidor El servidor devuelve una respuesta al cliente El servidor cierra la conexin
HTTP
Especificacin de HTTP:
http://www.w3.org/Protocols/rfc2616/rfc2616 .html Bsicamente debemos saber que los comandos principales son HTTP GET y POST.
Tecnologa Servlet
Piedra angular del desarrollo de aplicaciones
web en Java
Los JSPs son de hecho servlets disfrazados
Ventajas
Rendimiento cada peticin es procesada por un nico proceso en el contenedor de servlets Portabilidad heredado de Java Rpido desarrollo acceso a las riqusimas libreras de Java Robustez gestionados por la mquina virtual
de Java (garbage collection) Amplio soporte muchos desarrolladores y compaas utilizan esta tecnologa
Arquitectura
Servlet Container = servidor web capaz de
HTTP Request
Servlet
Browser
HTTP Response
Funcionamiento de un Servlet
Recibir Peticin
NO
Es el servidor reciente? S
NO
Cargar Servlet
Procesar Peticin
Enviar Respuesta
Contenedor Tomcat 5
El contenedor de Servlets ms popular Actualmente en la versin 5.0 Open source, disponible en:
Instalando Tomcat 5
Requisitos:
Haber instalado Java 5
Extraer fichero: downloads\Tomcat5.5\jakartatomcat-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>
2. 3. 4.
5. 6.
Tomcat para tu aplicacin Escribir el cdigo del servlet Compilar el cdigo Crear un descriptor de explotacin (deployment descriptor) Ejecutar Tomcat Invocar el servlet desde un navegador
El directorio %TOMCAT_HOME%/webapps es dnde cuelgas tus aplicaciones Una aplicacin 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 aplicacin myapp, que aparecer en la url a tu aplicacin Crear el directorio WEB-INF debajo de myApp
Crear subdirectorio clases Crear subdirectorio lib
Podis hacer copy/paste del contenido del directorio examples\servlets\ej1_holamundo_servlet bajo %TOMCAT_HOME\webapps\myapp
Vamos a reutilizar continuamente el contexto myapp
Compilar el Cdigo
Guardar el cdigo en
Crear el web.xml
Nombre recibido por el deployment
descriptor
Debe colocarse en el directorio WEB-INF
como elemento raz: <web-app> Se pueden encontra n elementos <servlet> que cuelgan de l
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>
Ejecutar el Cdigo
Arrancar Tomcat si es necesario, mediante el
Servlets: Jerarqua
La jerarqua de clases java es...
Las APIs
Dos paquetes permiten la programacin de
servlets:
javax.servlet
javax.servlet.http
Revisar documentacin:
Arrancar Tomcat Visitar: http://localhost:8080
destroy INICIALIZACIN: Una nica llamada al mtodo init por parte del servidor. Incluso se pueden recoger unos parametros concretos con getInitParameter de ServletConfig. SERVICIO: una llamada a service() por cada invocacin al servlet
Cuidado! El contenedor es multihilo
cliente cesen o un temporizador del servidor as lo indique. Se usa el mtodo destroy Revisar documentacin de la clase javax.servlet.Servlet
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 gestin.
se estn ejecutando en el mtodo service Proporcionar una finalizacin correcta haciendo que los procesos largos que aun no hayan concluido puedan terminar correctamente en el mtodo destroy del servlet. En ciertos casos poder terminar los procesos que aun siguen en ejecucin si es necesario.
Recuperando Configuracin
Recuperando informacin de configuracin del fichero web.xml <servlet> <servlet-name>ConfigDemoServletExample</servlet-name> <servlet-class>ConfigDemoServlet</servlet-class> <init-param> <param-name>adminEmail</param-name> <param-value>dipina@ilargi.org</param-value> </init-param> <init-param> <param-name>adminContactNumber</param-name> <param-value>6542214213</param-value> </init-param> </servlet>
Recuperando Configuracin
Se puede obtener una referencia a l mediante el mtodo ServletConfig.getServletContext() Algunos mtodos 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
Peticines y Respuestas
En el mtodo service() los parmetros:
ServletRequest representa la peticin del cliente y ServletResponse la respuesta del servidor getParameterNames getParameter getRemoteAddress getRemoteHost getWriter
examples\servlets\ej5_requestresponse_servlet
Clase GenericServlet
El uso de la interfaz Servlet tiene dos
inconvenientes:
Hay que proveer implementaciones de los cinco
mtodos de Servlet Hay que cachear la referencia a ServletConfig pasada como parmetro
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>"); } }
Paquete javax.servlet.http
Normalmente siempre vamos a trabajar con l cuando programemos servlets. Sus miembros y mtodos son ms convenientes y ofrecen ms funcionalidad Principalmente vamos a tratar con tres clases:
HttpServlet HttpServletRequest HttpServletResponse
HttpServlet
Hereda de GenericServlet Tiene 6 mtodos doXXX que son invocados cada
GET /query.html?keyword='diego' HTTP/1.1 Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.msexcel, application/vnd.ms-powerpoint, application/msword, application/x-shockwaveflash, */* Accept-Language: es,eu;q=0.7,en-gb;q=0.3 Accept-Encoding: gzip, deflate User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322) Host: localhost:9999 Connection: Keep-Alive
POST: Lo mismo que GET pero los parmetros van en lnea aparte dentro del cuerpo de la peticin. El manejo es idntico pero a travs del mtodo 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://localhost:9999/search.html Accept-Language: es,eu;q=0.7,en-gb;q=0.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: localhost:9999 Content-Length: 13 Connection: Keep-Alive Cache-Control: no-cache keyword=diego
Servlets: Mtodos
Por defecto retornan BAD_REQUEST(400) Son llamados desde el mtodo 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.
Una manera es usando el mtodo setHeader de HttpServletResponse. Al ser un proceso tan comn existe un mtodo que nos lo soluciona directamente: setContentType de HttpServletResponse.
Revisar
examples\servlets\ej6_dogetdopost_se rvlet
complejo. En Servlets usar getParameter de HttpServletRequest que devuelve (si no hay valor) o null (si no existe).
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 lnea directamente con getReader o getInputStream de HttpServletRequest. Revisar: examples\servlets\ej7_listparams_servlet
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 codificacines de datos (por ejemplo gzip) que el navegador cliente soporta y conoce. As el servlet puede consultar explcitamente informacin de codificacin y as aprovechar las ventajas de HTML gzipeado indicndolo en la cabecera de respuesta Content-Encoding.
un servlet. Para ello se puede hacer polimorfismo del mtodo getServletInfo que debe devolver un String. Revisar: examples\servlets\ej8_listheaders_se rvlet
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>"); } }
acceso concurrente.
cada vez, nicamente hay que hacer que nuestra clase, adems de heredar de HttpServlet, implemente la interfaz SingleThreadModel que es una interfaz sin mtodos.
objeto HttpServletRequest y el contexto del servlet. Estas variables pueden ser proporcionadas por:
cabeceras). Del socket en s (la IP). De los parmetros de instalacin del servidor web (los mapeos de las URL a los paths).
SERVER_SOFTWARE
Informacin de identificacin del servidor web getServletContext().getServerInfo()
Una lnea de estado (200 OK). Cabeceras de respuesta. Una lnea en blanco. Un documento.
La lnea de estado indica la versin del protocolo http y un cdigo de estado para indicar diferente informacin al cliente:
Enviar al usuario a otros enlaces. Indicar que el contenido es una imagen, PDF... Requerir un password.
Usar el mtodo setStatus de HttpServletResponse. Un mensaje: Suele estar relacionado con el cdigo de estado.
303
See Other Lo mismo que 301/302. (HTTP 1.1) 304 Not Modified Cuando se determina que el cliente hace una peticin 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 debera ser accedido por el proxy indicado en la cabecera Location. (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 peticin. (HTTP 1.1) 409 Conflict Generalmente en mtodo PUT. Suele enviarse si se ha solicitado una versin incorrecta de un recurso. (HTTP 1.1)
despus de un intervalo designado Decir cuanto tiempo va a estar el fichero usando conexiones persistentes ...
El mtodo ms general para indicar una cabecera de respuesta es setHeader de HttpServletResponse y recibe 2 strings:
1. 2.
que pasar una fecha Java (Date) a milisegundos. ENTEROS: setIntHeader para ahorrar el tener que pasar un entero a String.
indicada en la respuesta mediante el mtodo containsHeader. Para aadir un valor a una cabecera que ya haya sido seleccionada, se usan los mtodos addHeader, addDateHeader y addIntHeader.
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 lneas Set-Cookie). "sendRedirect" selecciona la cabecera Location y el cdigo de estado 302.
Para acceder al RequestDispatcher hay que recoger el contexto del servlet mediante el mtodo getServletContext.
Una vez tenemos el recurso accesible podemos: Hacer que el recurso sea el encargado de dar la respuesta a la peticin. Usamos el mtodo forward por lo que no podemos responder nosotros. Hacer una respuesta conjunta a la peticin entre el recurso y nuestro servlet usando el mtodo include
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 aplicacin.
setAttribute de ServletContext. Esto se suele hacer en la inicializacin del servlet. El control de que varios servlets manejen un mismo atributo es responsabilidad del desarrollador. Recoger un atributo: Se usa el mtodo getAttribute de ServletContext. Hay que convertir el objeto que devuelve al tipo requerido.
Reenviando Respuestas
Es posible delegar el procesamiento de un servlet a otro mediante la clase
Reenviando Respuestas
Para obtener un objeto RequestDispatcher:
A partir del mtodo getRequestDispatcher o
getNamedDispatcher de javax.servlet.ServletContext path recibido relativo al directorio raz del servidor o nombre del recurso El mtodo getRequestDispatcher de javax.servlet.ServletRequest recibe un path como parmetro relativo a la peticin actual HTTP
Reenviando Respuestas
// Revisar: examples\servlets\ej10_include_servlet RequestDispatcher rd = request.getRequestDispatcher("/servlet/SecondSe rvlet?name=diego"); rd.include(request, response); // Revisar: examples\servlets\ej11_forward_servlet RequestDispatcher rd = request.getRequestDispatcher("SecondServlet"); rd.forward(request, response);
Gestin de Sesiones
HTTP no tiene estado Necesario utilizar trucos para permitirlo:
Reescritura de urls Campos hidden <input type=hidden
evitar el login y password. Personalizar las webs recordando cada peculiaridad de cliente. Publicidad enfocada (personalizada) dado que se puede almacenar informacin sobre las preferencias del usuario mientras navega, busca informacin etc.
que se aplica la cookie. Por defecto la cookie se devuelve a la misma direccin que la envi, pero as podemos indicar que se reenve 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 sesin.
cookie. getPath/setPath: Indica a que rutas responde la cookie. Si no se indica nada, la cookie se enva para cualquier pgina en el mismo path actual. Se podra usar para usos generales como someCookie.setPath("/"). Hay que incluir al menos el directorio actual. getSecure/setSecure: Slo vale para sesiones seguras (e.i. SSL).
cookie. getVersion/setVersion: Indicar con que version del protocolo funciona esta cookie.
response.addCookie(Cookie)
reenva cada vez que accede al recurso se usa el mtodo getCookies de HttpServletRequest que devuelve un array de cookies. Con los mtodos getName y getValue de Cookie se accede a la informacin de la cookie.
estados. Se complican mucho las tareas de guardar las acciones (e.i. Compras) de un usuario. 3 posibles soluciones:
Cookies. Aadir informacin en la URL Usar campos ocultos de formularios (HIDDEN)
Revisar:
examples\servlets\ej12_cookie_servlet
tcnica: 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.
ASOCIADO A UNA PETICIN: Se usa el mtodo getSession de HttpServletRequest que devuelve null si no hay una sesin asociada. Entonces podramos crear una pero al ser una tarea sumamente comn, se pasa true y l mismo se encarga de crear una.
Usar los mtodos getValue (o getAttribute para versiones del API Servlet 2.2+) que devuelve un Object o null. Para asignar un valor dentro de una sesin se usa el mtodo putValue (o setAttribute para versiones del API Servlet 2.2+). Para conocer los nombres de los valores estn los mtodos getValueNames (o getAttributeNames para versiones del API Servlet 2.2+) que devuelve un Enumeration. Existen otros mtodos que aportan informacin sobre la sesin.
putValue y setAttribute eliminan (machacan) el valor anterior del atributo por lo que para aadir informacin hay que recuperar el valor primero y despus de modificarlo, volver a pasarlo a la sesin. INVALIDAR UNA SESION: Automticamente el servidor web invalida tras un periodo de tiempo (30) sin peticiones o manualmente usando el mtodo invalidate.
Revisar:
examples\servlets\ej13_session_servlet
Servidor
diferentes de drivers:
Puente ODBC-JDBC ms el driver ODBC
Traduce JDBC en ODBC No adecuado si parte cliente es annima
Necesidad de registrar fuente ODBC en cada mquina
JDBC URLs
URL: esquema de nombres para
localizar BD Sintaxis:
jdbc:<subprotocolo>:<subnombre> jdbc:odbc:cliente jdbc:msql://www.deusto.es:1112/c
atalogo jdbc:mysql://localhost:3306/docm an
Carga de un driver
Crea instancia de si mismo Se registra con el gestor
String myDriver = sun.jdbc.odbc.JdbcOdbcDriver; Class.forName(myDriver);
Conexin a la BD:
String url = jdbc:odbc:clientes; String user = dba; String pass = sql; Connection dbCon = DriverManager.getConnection(url, user, pass);
executeQuery() 1 conjunto de resultados ResultSet 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, crtica)); execute () Cuando no se sabe que va a devolver ResultSet o n
3 posibilidades:
Otras posibilidades:
PreparedStatement, se genera el plan de acceso la primera vez que se solicita la ejecucin
PreparedStatement ps = dbCon.prepareStatement(sqlString);
Defecto automtico (1 SQL 1 commit) Deshabilitar (N SQL 1 commit o rollback) dbCon.setAutoCommit(false); dbCon.commit();
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();
SQL se denomina lenguaje anfitrin Objetivo: insertar sentencias SQL en aplicaciones codificadas en cualquier lenguaje:
separar las instrucciones de SQL inmerso y el cdigo del lenguaje anfitrin:
C, C++, COBOL, FORTRAN, Pascal, ADA y Java Identificadores especiales para cada lenguaje, se usan para 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;
Desventajas:
BD debe ser conocida y su esquema accesible en
String vName; int vSalary; String vJob; Java.sql.Timestamp vDate; ... ESTTICO 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; ... DINMICO JDBC PreparedStatement 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();
public void init() { try { Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); System.out.println("JDBC driver loaded"); } catch (ClassNotFoundException e) { System.out.println(e.toString()); } }
Servlet Filters
Un filtro te da acceso a los objetos
HttpServletRequest y HttpServletResponse antes y despus, 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 <filtermapping>
Se puede asociar un filtro a un patrn de url Adems los filtros se pueden encadenar
Ejemplo Filter
// compile: javac -classpath %TOMCAT_HOME%\common\lib\servletapi.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; }
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; } }
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>
Servlet
Son flexibles y muy potentes Sin embargo, es muy lioso mezclar cdigo de
Java
SOLUCIN JSP