EL CAMINO A LA CERTIFICACION CON SERVLETS Y JSP EL CAMINO A LA CERTIFICACION CON SERVLETS Y JSP SCWCD RAFAEL ALCOCER CALDERA.

Tamaño: px
Comenzar la demostración a partir de la página:

Download "EL CAMINO A LA CERTIFICACION CON SERVLETS Y JSP EL CAMINO A LA CERTIFICACION CON SERVLETS Y JSP SCWCD RAFAEL ALCOCER CALDERA."

Transcripción

1 EL CAMINO A LA CERTIFICACION CON SERVLETS Y JSP EL CAMINO A LA CERTIFICACION CON SERVLETS Y JSP SCWCD RAFAEL ALCOCER CALDERA Página 1

2 SOBRE EL AUTOR SOBRE EL AUTOR Página 2

3 SOBRE EL AUTOR Nací en México, D.F. Estudié en la Facultad de Ingeniería de la UNAM la carrera de Ingeniero Mecánico-Electricista área Eléctrica y Electrónica. Tesis: Aplicación de un PLC en el Control de Máquinas de C.D. Más de 10 años de servicio profesional. 13 años de experiencia como programador Java (Swing). 6 años de experiencia como Desarrollador de Componentes Web (Servlets, JSP, Filters, Listeners). 5 años de experiencia con el uso de frameworks tales como Spring y Struts. 2 años de experiencia como Desarrollador de Componentes de Negocio (EJB). 2 años de experiencia como Arquitecto Java. 1 año de experiencia como Desarrollador JSF, Primefaces CERTIFICACIONES: Sun Certified Programmer for the Java 2 Platform de Noviembre de 2003 Sun Certified Business Component Developer for J2EE de Enero de 2006 Sun Certified Web Component Developer for the Java 2 Platform, Enterprise Edition de Noviembre de 2007 Oracle Certified Master, Java EE 5 Enterprise Architect 30 de Abril de 2009 (part 1) 24 de Mayo de 2011 (part 3) 27 de Julio de 2011 (part 2) Página 3

4 SOBRE EL AUTOR COMPUTACION: Reparación, mantenimiento y ensamble de computadoras. Configuración de hardware, software y redes. Desarrollamos un programa de cómputo TECSO PAQUETE. Para programar máquinas contadoras de monedas, en QBASIC y microcontrolador 68HC05 y también se adaptaría con el PIC16F84. No. de Registro Derechos de Autor: Desarrollé un programa RACCHEC Versión 1.0. Es un Reloj Checador para computadora utilizando Java y base de datos en Access. Posteriormente haría la versión 2.0 y en el año 2005 terminé la versión 2006 que está hecha en Swing y JVM y 5.0. No. de Registro Derechos de Autor: La base de datos no solo almacena la información, es la GUI para realizar las consultas e imprimir reportes. No. de Registro Derechos de Autor: Página 4

5 SOBRE EL AUTOR ELECTRONICA: Diseño e implementación de circuitos. Reparación y mantenimiento de equipo electrónico. Diseñé un programador de memorias 93C66 utilizando el microcontrolador PIC16F84, capaz de leer, escribir y borrar datos en la modalidad de 8 y 16 bits. No. de Registro Derechos de Autor: He diseñado Fuentes de Alimentación, Amplificadores, Crossover, Medidores de Nivel de Potencia, de Nivel de Líquidos, Termómetros, Cargadores de Baterías, Cerraduras Electrónicas, etc. Página 5

6 PREFACIO prefacio [Prefacio] Página 6

7 PREFACIO CANSADO DE LECTURAS TEDIOSAS, ABURRIDAS Y NO OBTENER RESULTADOS REALES CONOCE LOS TRUCOS DEL EXAMEN REAL PONTE A PRUEBA CON MAS DE 200 PREGUNTAS APRENDE LOS SECRETOS QUE SOLO LOS QUE HAN PASADO EL EXAMEN CONOCEN EN ESTE LIBRO PODRAS ENCONTRAR EL CAMINO PARA OBTENER TU CERTIFICACIÓN [Prefacio] Página 7

8 PREFACIO A quién está dirigido este libro? A aquellas personas que saben Java, no necesariamente expertas, que quieren aprender Servlets y JSP. Y saber que hay detrás de un examen de certificación (Sun Certified Web Component Developer). Por qué escribí este libro? Después de algunos años de trabajo en este medio he notado que hay muy pocos libros escritos en español referentes a Java. La mayoría de estos libros nos dan una base de cómo programar en Java pero ninguno de ellos nos habla de cómo aprobar un examen de certificación, o sea, no llegan al grado de detalle requerido para un examen de este calibre. Aclaro... libros escritos en español. Qué temas abarca este libro? Todos los relacionados al examen de certificación. Qué herramientas necesitas? - Java J2SDK 1.4 o superior. - Tomcat 5 o superior Qué requisitos necesitas? Para poder presentar este examen necesitas haber aprobado el Sun Certified Java Programmer. Cualquier versión. Cuántas preguntas contiene el examen? Son 69. Aunque no tengo idea si influya o no, al momento de presentar el examen y oprimir el botón START entras a un cuestionario en el cual te preguntan el nivel en el que te consideras en cada uno de los temas que se te van a preguntar. Te dan 15 minutos para contestarlo, te ponen un contador. Los niveles van desde EXPERT, INTERMEDIATE y le siguen otros dos. Mi duda es si dependiendo de estas respuestas se te genera el examen, no lo sé. La cuestión es que a mí me aparecieron 80 preguntas y no 69 y el tiempo que me dieron fueron 3 horas (175 minutos) en vez de 2. [Prefacio] Página 8

9 PREFACIO Cómo son las preguntas? Como las que aparecen en este libro. Cuánto cuesta el examen? Actualmente en la página de Sun aparece un costo de $200 dólares. Cuando yo lo pagué aquí en México me cobraron $150 dólares + IVA = $ dólares (en ese momento el dólar estaba en $11.15 y pague $ ). Me dijeron que el costo en México no había aumentado. Cuál es la calificación para pasar el examen? Necesitas 43 respuestas correctas (62%). Qué obtienes después del examen? Antes de salir del centro autorizado prometric donde realizaste el examen te van a entregar un reporte de examen. En él te muestra los porcentajes obtenidos en cada área y si pasaste o no. Este reporte te aparece justo después de que oprimes END a tu examen, te aparecen otros botones SHOW REPORT (te muestra lo anterior en pantalla) y PRINT (te imprime el reporte). A mí me dijeron que podía imprimir el reporte 3 veces, pero solo te dan un reporte. Cómo te registras para el examen? Después de pagar el costo del examen en el Centro de Servicios Educacionales de Sun te van a dar un voucher el cual contiene un número y una fecha de expiración (te dan un año): Voucher #: HOLA123 Exp Date: 12/24/2009 Tienes que ingresar a para localizar los centros autorizados para realizar el examen. Una vez que seleccionaste el centro donde quieres presentarlo entonces calendarizas la fecha y hora en que quieres realizarlo y en esos pasos te va a pedir ingresar el No. de Voucher. Cómo es el software del examen? Es como una aplicación Java posiblemente hecha en Swing y de fácil navegación. Puedes marcar las preguntas para después regresar a ellas. [Prefacio] Página 9

10 PREFACIO En que idiomas puedes presentar el examen? El examen por el momento solo viene en ingles, por eso mismo donde sea conveniente utilizaré palabras o la traducción completa de la pregunta y respuesta. Este libro lo escribí hace tiempo y nunca lo actualice. Por lo tanto, varias de las preguntas anteriores ya no aplican al día de hoy. Es más, Oracle absorbió a Sun MicroSystems. La certificación actual es: Oracle Certified Expert, Java EE 6 Web Component Developer De cualquier forma no pienses que el hecho de darle una leída a este libro te va a quitar el tiempo, al contrario las bases del web siguen siendo las mismas y aquí están explicadas. [Prefacio] Página 10

11 CONTENIDO CONTENIDO PORTADA 1 SOBRE EL AUTOR.. 2 PREFACIO 6 CONTENIDO.. 11 CAPíTULO 1 INTRODUCCION. 13 CAPíTULO 2 EL CONTENEDOR. 23 CAPíTULO 3 SERVLETS.. 28 CAPíTULO 4 atributos CAPíTULO 5 filtros 60 CAPíTULO 6 OYENTES (LISTENERS).. 73 CAPíTULO 7 LA SESION 81 CAPíTULO 8 JSP 98 [Contenido] Página 11

12 CONTENIDO CAPíTULO 9 EL Y JSTL. 140 CAPíTULO 10 TAGS PERSONALIZADOS CAPíTULO 11 SEGURIDAD CAPíTULO 12 PATRONES DE DISEÑO CAPíTULO 13 STRATEGY pattern [Contenido] Página 12

13 INTRODUCCIÓN CAPíTULO 1 introducción [Capítulo 1] Página 13

14 INTRODUCCIÓN Una aplicación web es un sistema que pueden utilizar los usuarios que tienen acceso a un servidor web a través de Internet por medio de una PC la cual tiene instalado un browser o navegador. En sus inicios cuando no había Internet una aplicación era llamada cliente-servidor, donde el programa se instalaba en cada PC del usuario. A pesar de que actualmente se siguen haciendo este tipo de aplicaciones resulta más costoso para efectos de soporte y menos eficiente. Sin embargo, una aplicación web resulta más sencilla de actualizar y mantener sin tener que instalar software en cada PC. Esta es una de las principales razones y ventajas de porque se usa más el web a diferencia de una aplicación hecha en swing. A pesar de que una aplicación hecha en swing se pueda subir a un servidor es necesario instalar en cada PC cliente el sistema. También es posible actualizar la aplicación swing de forma remota usando Java Web Start. Pero con todo lo anterior ha resultado mucho más sencillo usar la aplicación web para efectos de desarrollo de sistemas por las ventajas antes citadas. Existen numerosos lenguajes de programación empleados para el desarrollo de Aplicaciones Web, entre los que destacan: PHP ASP/ASP.NET Java, con sus tecnologías Java Servlets y JavaServer Pages (JSP) Perl Ruby Python Aunque ciertamente ASP no es un lenguaje de programación, sino una arquitectura de desarrollo web en la que se pueden usar por debajo distintos lenguajes (por ejemplo VB.NET o C# para ASP.NET, o VBScript/JScript para ASP). [Capítulo 1] Página 14

15 INTRODUCCIÓN ARQUITECTURA SERVIDOR DE APLICACIONES J2EE/JEE Un servidor de aplicaciones tiene un Contenedor EJB (Enterprise Java Beans) y un Contenedor Web (Servlets y JSP). JBOSS, Weblogic, WebSphere y Glassfish son ejemplos de servidores de aplicaciones. Tomcat es solo un Contenedor Web, no soporta EJBs esa es la diferencia. Qué hace un servidor web? Un servidor web toma la petición del cliente y le regresa algo al cliente. Qué hace un cliente web? Un cliente web le permite al usuario hacer peticiones al servidor y le muestra al usuario el resultado de esta petición. [Capítulo 1] Página 15

16 INTRODUCCIÓN SERVIDOR Cuando hablamos de servidores la realidad es que muchas veces no sabemos a qué se refieren. Bueno pues el servidor es la máquina física (PC) donde se instala el software de la aplicación (hardware y software). Por lo tanto, cuando decimos falló el servidor puede ser que la PC haya fallado, se apagó, le paso algo (físicamente) o el software de la aplicación falló. CLIENTE Es el usuario (humano) y/o el navegador (browser). NAVEGADO R USUARIO Dijo Usuario Humano! HuuMANooo! El browser o navegador es el software como Netscape, Mozilla o Internet Explorer que sabe como comunicarse con el servidor. De qué rayos habla, ni siquiera ha dado clic en el link Ejecuta mi petición en este instante [Capítulo 1] Página 16

17 INTRODUCCIÓN HTML (Hyper Text Markup Language) HTML le dice al browser o navegador como desplegar la información al usuario. HTTP (Hyper Text Transfer Protocol) Es el protocolo que usan los servidores y clientes en el web para comunicarse. El servidor usa HTTP para enviar HTML al cliente. Ejemplo en HTML para una página de login: <html> <head> <title>login</title> </head> <body> <h1>pagina DE LOGIN</h1> <form method="post" action="login"> Usuario: <input type="text" name="user" /><br /> Password: <input type="password" name="pass" /><br /> <input type="submit" /> </form> </body> </html> Elementos Clave de la Petición (request) - El método HTTP, que es la acción a realizar. - La URL, que es el path. - Los parámetros de la forma, que son como argumentos de un método. Elementos Clave de la Respuesta (response) - El estado del código, para saber si la petición fue exitosa. - El tipo de contenido (content type), ya sea texto, imagen, video, etc. - El contenido, que es el HTML. [Capítulo 1] Página 17

18 INTRODUCCIÓN Anatomía de la petición HTTP GET Método HTTP El path parámetros versión del protocolo línea de petición encabezados GET /abc/xyz/prueba.jsp?color=negro&fondo=gris HTTP/1.1 Host: User-Agent: Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-us; rv:1.4) Gecko/ Netscape 7.1 Accept: text/html,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain,q=0.8,video/xmng,image/png,image/jpeg,image/gif;q=0.2,*/*;q=0.1 Accept-Language=en-us,en;q=0.5 Accept-Encoding: gzip,deflate Accept-Charset: ISO ,utf-8;q=0.7,*;q=0.7 Keep-Alive: 300 Connection: keep-alive Anatomía de la petición HTTP POST Método HTTP El path versión del protocolo línea de petición encabezados cuerpo del mensaje (payload) POST /abc/xyz/prueba.do HTTP/1.1 Host: User-Agent: Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-us; rv:1.4) Gecko/ Netscape 7.1 Accept: text/html,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain,q=0.8,video/xmng,image/png,image/jpeg,image/gif;q=0.2,*/*;q=0.1 Accept-Language=en-us,en;q=0.5 Accept-Encoding: gzip,deflate Accept-Charset: ISO ,utf-8;q=0.7,*;q=0.7 Keep-Alive: 300 Connection: keep-alive color =negro&fondo=gris Anatomía de la respuesta HTTP versión del código de versión escrita del protocolo estado código de estado HTTP/ OK encabezados Set-Cookie: JSESSIONID=0AAB8C6DE666E3E6F490CF333bfca0c1; Path=/x Content-Type: text/html Content-Length: 500 Date: Mon, 10 Dec :24:10 GMT Server: Apache-Coyote/1.1 Connection: close cuerpo <html> </html> [Capítulo 1] Página 18

19 INTRODUCCIÓN Cosas que el Servidor no puede hacer solo Almacenar información en el servidor Contenido dinámico MIME TYPE El tipo de contenido (Content-Type) del valor del encabezado de la respuesta es conocido como MIME-TYPE. El MIME-TYPE le dice al navegador que tipo de dato el navegador está a punto de recibir para que el navegador sepa como traducirlo. PUERTO TCP El puerto TCP es solo un número. Un número de 16 bits que identifica un programa especifico de software en un servidor (hardware). Tienes en total (del 0 al 65535). Del 0 al 1023 son reservados para servicios conocidos. Ejemplos: FTP 21 Telnet 23 SMTP 25 Time 37 HTTPS 443 POP3 110 HTTP 80 [Capítulo 1] Página 19

20 INTRODUCCIÓN MI PRIMER SERVLET Vamos ahora hacer un ejemplo de un servlet y para continuar con la tradición utilizamos el clásico ejemplo del Hola Mundo, pero sin el MUNDO para salir de lo convencional. 1) Crear la clase HolaServlet import java.io.ioexception; import java.io.printwriter; import javax.servlet.servletexception; import javax.servlet.http.httpservlet; import javax.servlet.http.httpservletrequest; import javax.servlet.http.httpservletresponse; public class HolaServlet extends HttpServlet { public void doget(httpservletrequest request, HttpServletResponse response) throws ServletException, IOException { } } PrintWriter out = response.getwriter(); out.println("hola"); 2) Crear el archivo web.xml <?xml version="1.0" encoding="iso "?> <web-app xmlns=" xmlns:xsi=" xsi:schemalocation=" version="2.4"> </web-app> <servlet> <servlet-name>miprimerservlet</servlet-name> <servlet-class>holaservlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>miprimerservlet</servlet-name> <url-pattern>/hola</url-pattern> </servlet-mapping> [Capítulo 1] Página 20

21 INTRODUCCIÓN 3) Crear la página HTML hola.html <html> <head> <tiltle>mi PRIMER SERVLET</title> </head> <body> <form method="get" action="hola"> <input type="submit" /> </form> </body> </html> 4) Después de instalar Tomcat y dentro de webapps... crea una carpeta llamada hola dentro de hola crea otra carpeta llamada WEB-INF dentro de WEB-INF crea otra carpeta llamada classes 5) Ahora a ingresar los archivos a sus respectivas carpetas dentro de hola copia hola.html dentro de WEB-INF copia web.xml dentro de clases copia HolaServlet.class webapps hola hola.html WEB-INF classes web.xml HolaServlet.class [Capítulo 1] Página 21

22 INTRODUCCIÓN 6) Dentro de la carpeta bin de Tomcat se encuentra startup.bat, con este inicias el servidor 7) Abre una ventana del navegador que tengas instalado, por ejemplo Internet Explorer y escribe: 8) Te aparecerá: 9) Ahora da clic en el botón: [Capítulo 1] Página 22

23 El CONTENEDOR Capítulo 2 EL CONTENEDOR [Capítulo 2] Página 23

24 El CONTENEDOR Qué es un Contenedor? Cuando creas un programa en java tienes la posibilidad de utilizar el método publico, estático, sin tipo de retorno y con un arreglo de strings como argumento, main(), donde puedes ejecutar pruebas de tu programa con salida a la consola. Los servlets no tienen un método main() como lo puede tener cualquier clase java normal. Los servlets están bajo el control de otra aplicación java llamada Contenedor. Qué te proporciona el Contenedor? Soporte de comunicación Soporte de JSPs Soporte de multihilos (multithread) Manejo del ciclo de vida Seguridad declarativa (por medio del archivo web.xml) Cómo maneja una petición el Contenedor? 1) El usuario da clic en una liga que tiene una URL hacia un servlet. 2) El Contenedor ve que la petición es para un servlet así que crea dos objetos: a. HttpServletRequest (request) b. HttpServletResponse (response) request response [Capítulo 2] Página 24

25 El CONTENEDOR 3) El Contenedor encuentra el servlet correcto basado en la URL que viene en la petición. buscando servlet... 4) Crea o aloja un hilo (thread) para esa petición y llama al método service() del servlet pasándole los objetos request y response como argumentos. thread crear o alojar llamar service(request, response) 5) El método service() investiga cual método HTTP llamar basado en el método HTTP de la petición. Recuerda que la petición SIEMPRE incluye un método HTTP. EL METODO HTTP POR DEFAULT (EN CASO DE NO INCLUIR NINGUNO) ES GET, EN JSP. Hay algo que no me queda claro. Cuántos nombres puede tener el servlet? [Capítulo 2] Página 25

26 El CONTENEDOR Vamos a ver, si por ejemplo tenemos el sig. servlet: CLASE: import java.io.ioexception; import java.io.printwriter; import javax.servlet.servletexception; import javax.servlet.http.httpservlet; import javax.servlet.http.httpservletrequest; import javax.servlet.http.httpservletresponse; public class NombreUnoServlet extends HttpServlet { } public void doget(httpservletrequest request, HttpServletResponse response) throws ServletException, IOException { PrintWriter out = response.getwriter(); out.println("mi Servlet"); } web.xml <web-app...> </web-app> <servlet> <servlet-name>nombredos</servlet-name> <servlet-class>nombreunoservlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>nombredos</servlet-name> <url-pattern>/nombretres</url-pattern> </servlet-mapping> Página que hace la petición al servlet: <html> <head> <title>mi Servlet</title> </head> <body> <form method="get" action="nombretres"> <input type="submit" /> </form> </body> </html> [Capítulo 2] Página 26

27 El CONTENEDOR Mi pregunta para ti es ahora: Cuántos nombres ves? PERFECTO! Son 3: 1. El nombre de la clase: NombreUnoServlet 2. El nombre con el que fue desplegado ( deployado"), mapeado en el archivo web.xml: NombreDos 3. El nombre de la URL, que es el que conoce el cliente: nombretres DESCRIPTOR DE DESPLIEGUE En ingles: Deployment Descriptor Es el archivo web.xml punto. A veces lo podemos ver como DD. Qué nos ofrece el Descriptor de Despliegue? El DD provee un mecanismo declarativo para personalizar tu aplicación web. Qué beneficios podemos obtener del Descriptor de Despliegue? Minimiza el volver a abrir nuestro código que ya sido probado. Te permite adaptar tu aplicación a diferentes recursos (como base de datos) sin tener que recompilar y probar el código. Te permite controlar la seguridad. Te facilita el mantenimiento. Permite a gente no programadora modificar y desplegar tu aplicación, sin modificar el código. [Capítulo 2] Página 27

28 SERVLETS Capítulo 3 SERVLETS [Capítulo 3] Página 28

29 SERVLETS OBJETIVOS DEL EXAMEN Sección 1: El Modelo de la Tecnología Servlet Para cada uno de los métodos HTTP (tales como GET, POST, HEAD, etc.) describe el propósito del método y las características técnicas del protocolo del método HTTP, lista los disparadores que pueden causar que un cliente (generalmente un navegador Web) use el método; e identifica el método HttpServlet que corresponda al método HTTP. Usando la interfaz HttpServletRequest, escribe código que obtenga los parámetros de la forma desde la petición o solicitud, obtener información del encabezado de la petición HTTP u obtener las cookies de la petición. Usando la interfaz HttpServletResponse, escribe código que fije el encabezado de una respuesta HTTP, el tipo de contenido de una respuesta, adquirir un flujo de texto para la respuesta, adquirir un flujo binario para la respuesta, redireccionar una petición HTTP a otra URL o agregar cookies a la respuesta. Describir el propósito y la secuencia de eventos del ciclo de vida del servlet: (1) carga de la clase del servlet, (2) instanciación del servlet, (3) llamado al método init(), (4) llamado al método service y (5) llamado al método destroy. [Capítulo 3] Página 29

30 SERVLETS SERVLET Qué es un servlet? De acuerdo a la especificación 2.4 de servlets, es un componente web basado en tecnología java. CICLO DE VIDA DE UN SERVLET No Existe constructor init() destroy() service() Contenedor Web Clase Servlet Objeto Servlet Contenedor Cargar clase Instanciar servlet (el constructor se ejecuta) init() service() destroy() [Capítulo 3] Página 30

31 SERVLETS JERARQUIA DE CLASES DEL SERVLET <<interface>> javax.servlet.servlet void.init(servletconfig) void destroy() void service(servletrequest, ServletResponse) String.getServletInfo() ServletConfig...getServletConfig() <<abstract>> javax.servlet.genericservlet void init(servletconfig) void destroy() void service(servletrequest, ServletResponse) String.getServletInfo() ServletConfig...getServletConfig() void init() String.log(String) String.log(String, Throwable) String.getInitParameter(String) Enumeration...getInitParameternames() ServletContext.getServletContext() String.getServletName() <<abstract>> javax.servlet.http.httpservlet void service(servletrequest, ServletResponse) void service(httpservletrequest, HttpServletResponse) void dopost(httpservletrequest, HttpServletResponse) void doget(httpservletrequest, HttpServletResponse) void dohead(httpservletrequest, HttpServletResponse) void doput(httpservletrequest, HttpServletResponse) void dooptions(httpservletrequest, HttpServletResponse) void dodelete(httpservletrequest, HttpServletResponse) void dotrace(httpservletrequest, HttpServletResponse) long getlastmodified(httpservletrequest) La interfaz javax.servlet.servlet contiene los métodos del ciclo de vida del servlet. [Capítulo 3] Página 31

32 SERVLETS Cuándo se llaman estos métodos? init(): El Contenedor llama init() en una instancia del servlet después de que la instancia fue creada pero antes de que el servlet pueda servir cualquier petición del cliente. service(): El Contenedor llama service() cuando llega la primer petición de un cliente. El Contenedor crea un nuevo hilo o aloja uno del pool y hace que el método service() sea invocado. doget()/dopost(): El método service() invoca doget()/dopost() basado en el método HTTP que viene en la petición. Recuerda que la petición siempre contiene un método HTTP. Para que son? init(): Te da la oportunidad de inicializar tu servlet antes de manejar cualquier petición. service(): Invoca al método correspondiente doget(), dopost(), etc. En base al método HTTP que viene en la petición. doget()/dopost(): Aquí es lo bueno. Este es el método que ejecuta el código que quieres en tu aplicación web. Se pueden sobrescribir? init(): Sí. Si tienes código de inicialización (como obtener la conexión a la base de datos o registrarte con otros objetos), entonces conviene sobrescribir este método. service(): Sí. Pero muy rara vez lo debes hacer. Tu obligación es sobrescribir los métodos doget(), dopost(), etc. doget()/dopost(): Sí. Siempre debes sobrescribir al menos uno de estos métodos. Si no sobrescribes dopost(), por ejemplo, entonces le estas diciendo al Contenedor que el servlet no soporta la petición HTTP POST. [Capítulo 3] Página 32

33 SERVLETS SECUENCIA DE EVENTOS CUANDO EL CONTENEDOR MANEJA UNA PETICION El Contenedor crea una instancia del servlet y esta instancia recibe peticiones por parte del cliente, al recibir una petición crea o aloja un hilo (thread) para esa petición. Por lo tanto, el decir que cada petición crea una instancia del servlet esta mal. Es una sola instancia y muchos hilos. Es un hilo por cada petición. Existe un solo caso en el que sí se crea un servlet por petición llamado SingleThreadModel, que no vale la pena mencionarlo ya que no es bueno su uso. En el examen de certificación anterior a la versión 1.4 se hacían preguntas sobre este modelo, ahora ni se menciona. Qué sucede en aplicaciones distribuidas? En este caso habrá una instancia del servlet por cada JVM. Cuándo inicia su vida un servlet? El servlet inicia su vida cuando el Contenedor encuentra la clase del servlet. [Capítulo 3] Página 33

34 SERVLETS INTERFAZ ServletConfig Se crea un objeto por servlet. Se usa para pasar información en tiempo de despliegue a un servlet. Se usa para acceder al ServletContext. Los parámetros son configurados en el DD. INTERFAZ ServletContext La interfaz ServletContext define la vista del servlet de la aplicación web dentro de la cual el servlet esta ejecutándose. Se crea un objeto por aplicación web. Se usa para acceder parámetros de la aplicación web (configurados en el DD). Se usa para obtener información del servlet incluyendo el nombre y la versión. Se usa para obtener y fijar atributos, como una especie de post-its, donde alguien los pega en un pizarrón y otros los pueden tomar. [Capítulo 3] Página 34

35 SERVLETS REQUEST La petición o solicitud. El objeto request encapsula toda información de la petición del cliente. JERARQUIA DE CLASES DE LA PETICION <<interface>> javax.servlet.servletrequest int getcontentlength() Object getattribute(string) void setattribute(string, Object) void removeattribute(string) Enumeration.getAttributeNames() InputStream..getInputStream() int getserverport() int getlocalport() int getremoteport() String.getParameter(String) Enumeration.getParameterNames() String[]..getParameterValues() <<interface>> javax.servlet.http.httpservletrequest String.getContextPath() String.getHeader(String) int getintheader(string) HttpSession.getSession() Cookie[] getcookies() String getquerystring() String getmethod() [Capítulo 3] Página 35

36 SERVLETS JERARQUIA DE CLASES DE LA RESPUESTA <<interface>> javax.servlet.servletresponse int.getbuffersize() ServletOutputStream getoutputstream() PrintWriter..getWriter() void.setcontenttype(string) <<interface>> javax.servlet.http.httpservletresponse void addheader(string) void addcookie(cookie) void senderror(string) void sendredirect(string) String.encodeURL(String) String.encodeRedirectURL(String) void setstatus() void setheader(string) Quién implementa las interfaces HttpServletRequest y HttpServletResponse? Quien crees? Nooooo... Exacto. El Contenedor. Quién determina si doget() o dopost() se ejecuta? El método HTTP. Recuerda: La petición del cliente siempre incluye un método HTTP, si no pones uno en el form el de default es GET. Si el método HTTP es GET el método service() llama a doget(). Si el método HTTP es POST el método service() llama a dopost(). [Capítulo 3] Página 36

37 SERVLETS METODOS HTTP GET POST HEAD TRACE PUT DELETE OPTIONS CONNECT Pregunta para obtener algo (un recurso o un archivo) en la URL que se hizo la petición. Le pregunta al servidor para que acepte la información anexada a la petición. Es como un GET++, un GET con información extra enviada a la petición. Pregunta únicamente por la parte del encabezado de cualquier cosa que pudiera traer el GET. Así que es como un GET pero sin cuerpo en la respuesta. Te da información sobre la URL peticionada sin regresarte lo real. Pregunta por una retroalimentación del mensaje de la petición, para que el cliente pueda ver lo que esta recibiendo del otro lado, para pruebas o problemas. Dice que ponga la información encerrada (el cuerpo) en la URL peticionada. Dice que borre algo (recurso o archivo) en la URL peticionada. Pregunta por una lista de métodos HTTP a los cuales lo que esta en la URL peticionada pueda responder. Dice que se conecte para efectos de túnel (tunneling). [Capítulo 3] Página 37

38 SERVLETS DIFERENCIA ENTRE GET Y POST GET Puede enviar parámetros en los datos. Esta limitado a lo que puedes anexar a la línea de petición. Los datos de los parámetros se muestran en la barra de entrada del navegador. No tiene cuerpo. Puede ser marcado. Es idempotent. POST Puede enviar parámetros en los datos. Los datos de los parámetros no se muestran en la barra de entrada del navegador. Tiene cuerpo. Esta es la clave. No puede ser marcado. No es idempotent. Cómo es eso que se muestran los datos de los parámetros? Si, para el caso de GET, los datos de los parámetros son mostrados en la barra de entrada del navegador, justo después de la URL y separados por?. Lo que significa que para una pagina de login no sería conveniente usar GET porque en la barra se vería la información del usuario y contraseña. A menos que le quieras decir a medio mundo que datos ingresaste. POST sería el más conveniente. Qué quiere decir con idempotent? Que puedes hacer la misma cosa una y otra vez sin tener consecuencias negativas o efectos secundarios. Método HTTP por default <html> <head> <title>método HTTP por Default</title> </head> <body> <form action="login">... </form> </body> </html> Si en nuestra forma no escribimos el método (<form method= POST action= login >) entonces el de default es GET. [Capítulo 3] Página 38

39 SERVLETS Qué pasa en el caso de tener múltiples valores para un solo parámetro, por ejemplo, cuando se usan casillas de verificación? No pasa nada. A parte de los parámetros Qué más puedes obtener de la petición? La plataforma del cliente y la información del navegador: String cliente = request.getheader("user-agent"); Los cookies asociados con esta petición: Cookie[] cookie = request.getcookies(); La sesión asociada con este cliente: HttpSession session = request.getsession(); El método HTTP de la petición: String metodohttp = request.getmethod(); El flujo de entrada (input stream) de la petición: InputStream is = request.getinputstream(); Cuál es la diferencia entre getheader() y getintheader()? getheader() siempre te regresa un String y getintheader() es un método conveniente para evitarte hacer la conversión a entero. Por ejemplo: String maxforwards = request.getheader( Max-Frowards ); int imaxforward = Integer.parseInt(maxForwards); Sería lo mismo con: int imaxforwards = request.getintheader(( Max-Frowards ); [Capítulo 3] Página 39

40 SERVLETS Diferencias entre getremoteport(), getlocalport() y getserverport() Yo creo que lo más difícil de entender aquí es el primer método, getremoteport(), obtener el puerto remoto. Pero la pregunta sería: Quién es remoto? Como es el servidor el que esta preguntando entonces el que es remoto es el cliente. Por lo tanto, getremoteport() obtiene el puerto del cliente. getserverport() nos dice hacia cual puerto la petición fue originalmente enviada. getlocalport() nos dice en cual puerto finalmente termino la petición. Pero cual es la diferencia de lo de arriba hacia donde se envía originalmente y en donde termina finalmente, o sea, lo envías a un lado y termina en otro? Así es, las peticiones son enviadas a un solo puerto, donde el servidor esta esperando por peticiones, pero el servidor puede encontrar un puerto local diferente por cada hilo de ejecución para que la aplicación pueda manejar varios clientes al mismo tiempo. [Capítulo 3] Página 40

41 SERVLETS package com.download; Código para Bajar un Archivo JAR import java.io.ioexception; import java.io.inputstream; import javax.servlet.servletcontext; import javax.servlet.servletexception; import javax.servlet.servletoutputstream; import javax.servlet.http.httpservlet; import javax.servlet.http.httpservletrequest; import javax.servlet.http.httpservletresponse; public class BajarJar extends HttpServlet { public void doget(httpservletrequest request, HttpServletResponse response) throws ServletException, IOException { response.setcontenttype("application/jar"); int read = 0; byte[] bytes = new byte[1024]; ServletOutputStream os = response.getoutputstream(); ServletContext ctx = getservletcontext(); InputStream is = ctx.getresourceasstream("/x.jar"); while ((read = is.read(bytes))!= -1) { os.write(bytes, 0, read); } } } os.flush(); os.close(); Cómo le dices al navegador lo que quieres bajar? Diciéndole el tipo de contenido, con la instrucción: response.setcontenttype(string mime-type); Qué significa el tipo de contenido? El tipo de contenido es el Mime Type. [Capítulo 3] Página 41

42 SERVLETS Dónde se encuentra el archivo jar que se va a bajar? Si nuestra aplicación se llama downloadjar y si utilizamos Tomcat como servidor, entonces dentro de webapps/downloadjar/x.jar, es donde debe ir. El método getresourceasstream() requiere que inicies la ruta con el forward slash (/), el cual representa la raíz de tu aplicación web. webapps downloadjar x.jar WEB-INF classes web.xml text/html application/pdf application/jar application/x-zip application/java application/octet-stream image/jpeg video/quicktime MIME TYPES Comunes [Capítulo 3] Página 42

43 SERVLETS La respuesta. RESPONSE JERARQUIA DE CLASES DE LA RESPUESTA <<interface>> javax.servlet.servletresponse int.getbuffersize() ServletOutputStream getoutputstream() PrintWriter..getWriter() void.setcontenttype(string) <<interface>> javax.servlet.http.httpservletresponse void addheader(string) void addcookie(cookie) void senderror(string) void sendredirect(string) String.encodeURL(String) String.encodeRedirectURL(String) void setstatus() void setheader(string) Cuántas opciones tienes para la salida? Tienes 2 opciones: 1. Caracteres de datos (PrintWriter) 2. Flujos de bytes (ServletOutputStream) PrintWriter Se usa para imprimir texto a un flujo de caracteres. Aunque puedes escribir caracteres a un OutputStream, PrintWriter es el que esta diseñado para manejar caracteres. En realidad PrintWriter, encapsula el ServletOutputStream, esto es, tiene una referencia al ServletOutputStream y delega llamados a el. Hay solo un flujo de salida que se regresa al cliente pero el PrintWriter lo decora, agregando métodos de caracteres más amigables. [Capítulo 3] Página 43

44 SERVLETS Ejemplo con PrintWriter PrintWriter out = response.getwriter(); out.println("hola"); ServletOutputStream ServletOutputStream Ejemplo con ServletOutputStream ServletOutputStream os = response.getoutputstream(); os.write((bytearray); ENCABEZADOS Cual es la diferencia entre setheader() y addheader()? response.setheader("foo", "bar"); Si un encabezado con el mismo nombre ya existe en la respuesta, el valor es remplazado con este valor. En caso contrario, agrega un nuevo encabezado con este valor a la respuesta. response.addheader("foo", "bar"); Agrega un nuevo encabezado con este valor a la respuesta o agrega un valor adicional a un encabezado ya existente. response.setintheader("foo", 33); Este es un método conveniente que remplaza el valor de un encabezado ya existente con este nuevo valor entero o agrega un nuevo encabezado con este valor a la respuesta. De hecho cuando se llama a: response.setcontenttype("text/html"); Estas remplazando o agregando un encabezado como si dijeras: response.setheader("content-type", "text/html"); [Capítulo 3] Página 44

45 SERVLETS Redirect Cuando el servlet realiza un redireccionamiento quien realiza el trabajo es el navegador. Por ejemplo: response.sendredirect(" Este método fija los encabezados y cuerpo del contenido apropiados para redireccionar al cliente a otra URL diferente. El argumento de este método es un String pero este String es un URL. Puedes utilizar este método con una ruta relativa, esto es, con o sin el forward slash (/). Por ejemplo, si el cliente originalmente escribió: Cuando la petición llega al servlet llamado ejecutar.do, el servlet llama a sendredirect() con una URL relativa que NO comienza con el forward slash: response.sendredirect("cap4/hola.html"); El Contenedor construye la URL completa relativa a la URL original de la petición: Pero si el argumento de sendredirect() comienza con el forward slash: response.sendredirect("/cap4/hola.html"); El Contenedor construye la URL completa relativa al Contenedor Web, en vez de ser relativa a la URL original de la petición. Así que la nueva URL será: cap4 es una aplicación web separada de la aplicación web llamada aplicaciones [Capítulo 3] Página 45

46 SERVLETS Puedes utilizar sendredirect() después de haber escrito a la respuesta? No. Interfaz RequestDispatch Cuando se hacen aplicaciones web, es con frecuencia útil reenviar la petición a otro servlet o incluir la salida de otro servlet en la respuesta. La interfaz RequestDispatch nos ayuda en esto. El método getrequestdispatcher(string) puede obtenerse vía ServletRequest o ServletContext. Y tiene como argumento un String que describe la ruta. Si se utiliza el ServletContext esta ruta debe ser relativa a la raíz del ServletContext y DEBE comenzar con /. Si se utiliza ServletRequest puede o no llevar el /. Cuál es la diferencia entre Redirect y RequestDispatch? Redirect hace que el cliente, en este caso el navegador, haga el trabajo. RequesDispatch hace algo extra en el servidor. Recuerda lo sig: Redirect => cliente RequestDispatch => servidor Cuando el servlet hace un Redirect, es como decirle al cliente que mejor llame a otra persona. El cliente en este caso recuerda que es el navegador no el usuario. El navegador hace el nuevo llamado en nombre del usuario después de que la petición original dijo: Disculpa llama mejor a esta persona. El usuario entonces observa la nueva URL en el navegador. Cuando el servlet hace un RequestDispatch es como decirle a un compañero de trabajo que realice la chamba y le responda al cliente. Es como decir: compañero tómale la llamada. De esta forma el usuario nunca supo que esto pasó, porque la barra del navegador nunca cambio. Sin importar quien le tomo la llamada al cliente, éste obtuvo su respuesta. [Capítulo 3] Página 46

47 ATRIBUTOS Capítulo 4 ATRIBUTOS [Capítulo 4] Página 47

48 ATRIBUTOS OBJETIVOS DEL EXAMEN Sección 3: El Modelo del Contenedor Web Para los parámetros de inicialización del ServletContext: escribe código del servlet para acceder parámetros de inicialización; y crea los elementos del descriptor de despliegue para declarar los parámetros de inicialización. Para los ámbitos o alcances de los atributos del servlet fundamentales (request, session y context): escribe código del servlet para agregar, recuperar y quitar atributos; dado un escenario, identificar el ámbito o alcance apropiado para un atributo; e identifica problemas de multi-hilos asociados con cada ámbito o alcance. Describe el modelo de procesamiento de peticiones del contenedor Web; dado un problema de diseño, describe como aplicar un filtro o un empaquetador (wrapper). Describe el modelo de eventos del ciclo de vida del contenedor Web para peticiones, sesiones y aplicaciones Web; crea y configura clases oyentes para cada ciclo de vida del ámbito o alcance; crea y configura clases oyentes de atributos de ámbito o alcance y dado un escenario identifica el atributo oyente apropiado a usar. Describe el mecanismo de RequestDispatcher; escribe código de servlet para crear un despachador de peticiones; escribe código de servlet para forwardear o incluir el recurso objetivo e identifica y describe los atributos de ámbito o alcance adicionales proporcionados por el contenedor al recurso objetivo. [Capítulo 4] Página 48

49 ATRIBUTOS PARÁMETROS INICIALES EN EL SERVLET En muchas ocasiones dentro del servlet tenemos la tendencia a hard-codear nombres para obtener información que necesitamos. Esto es malo si tomamos en cuenta que después esa información podría cambiar. La consecuencia sería, reabrir esa clase del servlet para realizar la modificación necesaria, volver a compilar y volver a desplegar (deployar) el servlet. Cómo podríamos resolver el problema anterior? Cómo evitar tocar el código del servlet? Los servlets tienen parámetros iniciales Así es, los servlets tienen parámetros iniciales o parámetros de inicialización. Estos parámetros son declarados en el DD (web.xml) en forma de pares de cadenas (strings) nombre/valor. Ya en el servlet uno solicita el nombre y el resultado obtenido es el valor. De esta forma el nombre permanece invariable en el código del servlet y ya en el DD nosotros tenemos la posibilidad de modificar el valor cuando se requiera. [Capítulo 4] Página 49

50 ATRIBUTOS CICLO DE LECTURA 1. El Contenedor lee el DD (web.xml) para este servlet, incluyendo los parámetros iniciales (<init-param>). Contenedor lee web.xml 2. El Contenedor crea una nueva instancia de ServletConfig para este servlet. Contenedor new ServletConfig 3. El Contenedor crea un par de cadenas (String) nombre/valor para cada parámetro inicial del servlet. Asumiendo que solo tenemos uno: nombre Contenedor String parámetro inicial valor del DD String 4. El Contenedor le da al ServletConfig referencias de los parámetros iniciales nombre/valor. nombre String ServletConfig valor String [Capítulo 4] Página 50

51 ATRIBUTOS 5. El Contenedor crea una nueva instancia del servlet. Contenedor new Instancia del servlet 6. El Contenedor llama el método init() del servlet, pasando como argumento el SevletConfig. nombre String ServletConfig valor String Contenedor init(servletconfig) Instancia del servlet Cómo se declaran estos parámetros en el DD? <web-app...> <servlet> <servlet-name>pruebaservlet</servlet-name> <servlet-class>com.pruebas.pruebaservlet</servlet-class> <init-param> <param-name>prueba </param-name> </init-param> </servlet> <servlet-mapping> <servlet-name>pruebaservlet</servlet-name> <url-pattern>/prueba</url-pattern> </servlet-mapping> </web-app> [Capítulo 4] Página 51

52 ATRIBUTOS Cómo se obtienen estos parámetros en el servlet? package com.pruebas; import java.io.ioexception; import java.io.printwriter; import javax.servlet.servletconfig; import javax.servlet.servletexception; import javax.servlet.http.httpservlet; import javax.servlet.http.httpservletrequest; import javax.servlet.http.httpservletresponse; public class PruebaServlet extends HttpServlet { public void doget(httpservletrequest request, HttpServletResponse response) throws IOException, ServletException { ServletConfig config = getservletconfig(); String prueba = config.getinitparameter("prueba "); } } PrintWriter out = response.getwriter(); out.println("prueba " + prueba ); Cuántas versiones existen del método init()? Existen 2. Una que toma ServletConfig como argumento y otra que no tiene argumentos. init(servletconfig) init() El metodo init(servletconfig) llama al metodo init(), por eso, el método que conviene que sobrescribas en caso de que lo necesites es el que no tiene argumentos. Pero en caso de que sobrescribas el método init(servletconfig) necesitas agregar super.init(servletconfig). En realidad no es necesario que lo hagas ya que tú puedes obtener el ServletConfig llamando al metodo getservletconfig(). [Capítulo 4] Página 52

53 ATRIBUTOS Cuántas veces se leen los parámetros iniciales y cuando? Se leen una sola vez, cuando el Contenedor inicializa el servlet. Cuál es la principal tarea de ServletConfig? Proporcionar parámetros iniciales. Interfaz ServletConfig <<interface>> javax.servlet.servletconfig String.getInitParameter(String) Enumeration.getInitParameterNames() ServletContext.getServletContext() String.getServletName() Si realizo un cambio en el valor de mi parámetro inicial En qué momento lo puedo ver reflejado? Recuerdas el CICLO DE LECTURA? Que bueno porque yo no... Aquí un breve resumen: El Contenedor lee el DD (web.xml), los parámetros iniciales y crea el objeto ServletConfig. Igualmente crea un par de strings nombre/valor por cada parámetro inicial. Asigna una referencia de éstos al ServletConfig y crea la instancia del Servlet, llama al método init(servletconfig) pasándole el ServletConfig como argumento. Esto se hace UNA SOLA VEZ. Por lo tanto, los parámetros iniciales son leídos una sola vez y ya, cuando el contenedor inicializa el Servlet. Esto es, los parámetros iniciales no son leídos nuevamente. Respondiendo a la pregunta: En qué momento puedes ver reflejado los cambios hechos al valor de tu parámetro inicial? Hasta que vuelves de deployar el Servlet [Capítulo 4] Página 53

54 ATRIBUTOS PARAMETROS INICIALES EN LA APLICACIÓN Lo que vimos en la sección anterior Parámetros Iniciales en el Servlet referente al objeto ServletConfig, solo funciona para ese servlet, si otro servlet quiere invocar ese parámetro inicial no lo logrará. Cómo lograr que parámetros iniciales puedan ser leídos por toda mi aplicación? Una aplicación web tiene parámetros iniciales Así es, como el servlet... una aplicación web también tiene parámetros iniciales o parámetros de inicialización. Estos parámetros también son declarados en el DD (web.xml) en forma de pares de cadenas (strings) nombre/valor. Ya en la aplicación uno solicita el nombre y el resultado obtenido es el valor. De esta forma el nombre permanece invariable en el código de la aplicación y ya en el DD nosotros tenemos la posibilidad de modificar el valor cuando se requiera. [Capítulo 4] Página 54

55 ATRIBUTOS CICLO DE LECTURA 1. El Contenedor lee el DD (web.xml) y crea un par de cadenas (String) nombre/valor por cada <context-param> 2. El Contenedor crea una nueva instancia del servlet. 3. El Contenedor le da al ServletContext una referencia para cada par nombre/valor de los parámetros iniciales de contexto (de la aplicación). 4. Cada servlet y JSP desplegada (deployada) como parte de la aplicación web tiene acceso al mismo ServletContext. ServletConfig es uno por servlet. ServletContext es uno por aplicación web. NOTA: Podemos observar una letal y confusa inconsistencia en los nombres... ServletConfig y ServletContext. De haber realizado una encuesta seguramente esto no habría ocurrido. Bien pudo ser ServletConfig y AppConfig o ServletConfig y ApplicationConfig. ServletContext X Y Z ServletConfig ServletConfig ServletConfig ServletConfig Parámetros iniciales Parámetros iniciales Parámetros iniciales Ya que una JSP dentro del Servlet X dentro del Servlet Y dentro del Servlet X es convertida en servlet, ésta tiene su propio ServletConfig [Capítulo 4] Página 55

56 ATRIBUTOS Los parámetros de contexto <context-param> en realidad se debieron haber llamado parámetros de aplicación <app-param> o <application-param> o algo por el estilo. Por qué? Porque son parámetros que pueden ser leídos por toda la aplicación. Estos parámetros no pueden ser más que Strings. Cómo se declaran estos parámetros en el DD? <web-app...>... <context-param> <param-name>app </param-name> <param-value>app @alcocer.co.nf</param-value> </context-param>... </web-app> Cómo se obtienen estos parámetros en el Servlet? package com.pruebas; import java.io.ioexception; import java.io.printwriter; import javax.servlet.servletcontext; import javax.servlet.servletexception; import javax.servlet.http.httpservlet; import javax.servlet.http.httpservletrequest; import javax.servlet.http.httpservletresponse; public class PruebaAppServlet extends HttpServlet { public void doget(httpservletrequest request, HttpServletResponse response) throws IOException, ServletException { ServletContext app = getservletcontext(); String app = app.getinitparameter("app "); } PrintWriter out = response.getwriter(); out.println("app " + app ); } [Capítulo 4] Página 56

57 ATRIBUTOS Interfaz ServletContext <<interface>> javax.servlet.servletcontext String getinitparameter(string) Enumeration getinitparameternames() Object..getAttribute(String) Enumeration getattributenames() void..setattribute(string, Object) void..removeattribute(string) int..getmajorversion() int..getminorversion() String...getServerInfo() String getrealpath() RequestDispatcher getrequestdispatcher(string) InputStream getresourceasstream(string) URL..getResource(String) void..log(string) void..log(string, Throwable) De que maneras puedes obtener el ServletContext? Lo puedes obtener de dos formas diferentes: 1. El objeto ServletConfig del servlet siempre tiene una referencia al ServletContext. ServletConfig config = getservletconfig(); ServletContext app = config.getservletcontext(); 2. Directamente ServletContext app = getservletcontext(); [Capítulo 4] Página 57

58 ATRIBUTOS Nota: Para efectos del examen hubiera sido de mucha utilidad y hubiera sido muy distintivo el haber usado, como mencionamos en la nota anterior... ServletConfig y ApplicationConfig. De esta forma al llamar a nuestro parámetro lo haríamos así: ServletConfig config = getservletconfig(); String prueba = config.getinitparameter("prueba "); // Esto es pregunta de examen y es incorrecto ApplicationConfig app = getapplicationconfig(); String app = app.getappparameter("app "); Y por el puro nombre sabríamos a que parámetro nos referimos, sin embargo, el método getinitparameter() es igual para ServletConfig y para ServletContext. Si realizo un cambio en el valor de mi parámetro inicial de contexto En qué momento lo puedo ver reflejado? Recuerdas el CICLO DE LECTURA? Que bueno porque yo también... No pondré un breve resumen... Respondiendo a la pregunta: En qué momento puedes ver reflejado los cambios hechos al valor de tu parámetro inicial de contexto? Cuando la aplicación es redeployada (la aplicación se vuelve a desplegar). [Capítulo 4] Página 58

59 ATRIBUTOS Será posible cambiar el valor de los parámetros iniciales en tiempo de ejecución? No. No es posible De hecho en la API de ServletConfig y de ServletContext existen los métodos getinitparameter(), pero no hay ningún setinitparameter(). Estos parámetros iniciales son constantes. Pueden ser modificados sus valores pero hasta que se vuelve a hacer el deploy (despliegue) se puede ver reflejado el cambio. Son constantes en tiempo de despliegue no en tiempo de ejecución. Toma nota de lo siguiente: Si por ahí escuchas parámetro inicial y no especifican si es para el servlet o para la aplicación debes asumir que es para el servlet ya que en realidad los tags para el servlet dicen <init-param> Gracias. Lo tomaré en cuenta. La realidad es que uno como desarrollador no tiene porque estar suponiendo cosas. Tenemos que ser explícitos y decir a que nos referimos. [Capítulo 4] Página 59

60 FILTROS Capítulo 5 FILTROS [Capítulo 5] Página 60

61 FILTROS OBJETIVOS DEL EXAMEN Sección 3: El Modelo del Contenedor Web Describe el modelo de procesamiento de peticiones del contenedor web; dado un problema de diseño, describe como aplicar un filtro o un empaquetador (wrapper). Sección 11: Patrones Java EE Dada una descripción de un escenario con una lista de problemas, selecciona un patrón que pueda resolver el problema. La lista de patrones que debes conocer es: Intercepting Filter, Model-View-Controller, Front Controller, Service Locator, Business Delegate, y Transfer Object. Encaja patrones de diseño con declaraciones describiendo beneficios potenciales que aumente desde el uso del patrón para cualquiera de los siguientes patrones: Intercepting Filter, Model-View-Controller, Front Controller, Service Locator, Business Delegate, y Transfer Object. Este capítulo no incluye los patrones de diseño, este tema se verá más adelante, pero aquí aplicaremos el patrón Intercepting Filter. [Capítulo 5] Página 61

62 FILTROS INTRODUCCIÓN En términos técnicos, un FILTRO es un objeto que intercepta un mensaje entre una fuente de datos y un destino de datos y en ese "inter" filtra los datos que se están pasando entre ellos. Para una aplicación web, un FILTRO es un componente web que reside en un servidor web y filtra las peticiones y respuestas que son pasadas entre un cliente y un recurso. Los FILTROS son componentes java que te permiten realizar modificaciones al vuelo de la información contenida en el cuerpo del mensaje (payload) o en el encabezado de la petición hacia un recurso y de la respuesta desde un recurso. Un FILTRO es un fragmento de código reutilizable que puede transformar la información contenida en peticiones HTTP, respuestas y encabezados. Los filtros no crean una respuesta o responden a una petición como lo hace un servlet, en vez de eso modifican o adaptan las peticiones para un recurso y modifican o adaptan las respuestas desde un recurso. Los FILTROS pueden actuar en contenido dinámico o estático. [Capítulo 5] Página 62

63 FILTROS NOTA: En algunos libros cuando se habla de contenido dinámico y estático se refieren a recursos web. El desarrollador de la aplicación crea un filtro implementando la interfaz javax.servlet.filter con un constructor público y sin argumentos (el de default). La clase del filtro es empaquetada en el Archivo Web (WAR) junto con las otras clases de la aplicación incluyendo los servlets, contenido estático y JSPs. El filtro se declara en el DD (web.xml) muy parecido como se hace con el servlet. El Contenedor decide cuando invocar los filtros basándose en las declaraciones hechas en el DD (web.xml). En el DD la persona que realiza el despliegue (Deployer) mapea los filtros a patrones URL o a un servlet en particular por medio del nombre lógico del servlet. Por lo tanto, quien realiza el despliegue y no el programador es el que decide que subconjunto de peticiones o respuestas deben ser procesadas por qué filtros. [Capítulo 5] Página 63

64 FILTROS EJEMPLOS DE APLICACIÓN DE LOS FILTROS Para realizar AUTENTICACIÓN. Para controlar el acceso a un sistema por medio de la identificación de un usuario (LOGGING). Para conversión de imágenes. Para compresión de datos. Para encriptación. Para categorizar bloques de texto (TOKENIZING). Para disparar eventos de acceso a recursos. Para transformar contenido XML (XSL/T). Para encadenar el valor de respuesta del encabezado del tipo de contenido (MIME-TYPE). Para cuestiones de cache. [Capítulo 5] Página 64

65 FILTROS CICLO DE VIDA DEL FILTRO constructor init() destroy() dofilter() Después de desplegar la aplicación web y antes de que una petición ocasione que el Contenedor accese a un recurso web, el Contenedor debe encontrar la lista de filtros que deben ser aplicados a los recursos web. El Contenedor debe asegurarse de que se ha instanciado el filtro apropiadamente y entonces llamar a su método init(filterconfig). El filtro podría lanzar una excepción en caso de no funcionar correctamente. Por ejemplo, si la excepción es del tipo UnavailableException, el Contenedor podría examinar el atributo ispermanent de la excepción y podría reintentar el filtro más tarde. Por cada declaración <filter> que se haga en el DD (web.xml) se creara únicamente una sola instancia por Maquina Virtual de Java (JVM). Cuando el Contenedor recibe una petición, toma la instancia del primer filtro de la lista y ejecuta el método dofilter(). [Capítulo 5] Página 65

66 FILTROS Contenedor Web Clase Filtro Objeto Filtro Contenedor Cargar clase Instanciar filtro (el constructor se ejecuta) init() dofilter() destroy() [Capítulo 5] Página 66

67 FILTROS init(): Cuando el Contenedor decide instanciar el filtro se debe asegurar de que lo hizo apropiadamente entonces llama a su método init(filterconfig). Este método es llamado una sola vez durante el ciclo de vida del filtro. Este método es tu oportunidad de realizar cualquier ajuste en alguna tarea antes de que el filtro sea llamado (se llame su método dofilter()). Este método tiene un solo argumento, FilterConfig. La implementación más común de este método es guardar una referencia del objeto FilterConfig para usarlo más tarde en el filtro. public void init(filterconfig config) throws ServletException { // Código de inicialización // Generalmente se hace lo sig: // this.config = config; } dofilter(): Este método es análogo al método service() del servlet. El Contenedor llama a este método por cada petición con la URL que esta mapeada a este filtro. Este método tiene 3 argumentos: 1. ServletRequest 2. ServletResponse 3. FilterChain En este método implementas la funcionalidad del filtro. Por ejemplo, la validación de un usuario o la compresión de una respuesta. public void dofilter(servletrequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException { // Código } [Capítulo 5] Página 67

68 FILTROS destroy(): Cuando el Contenedor decide quitar la instancia de un filtro, entonces llama al método destroy(). Este método es tu oportunidad de realizar limpieza general antes de que la instancia sea destruida. Esto es, liberar recursos que fueron utilizados durante el uso del filtro. Este método no declara ninguna excepción. public void destroy() { // Realizar limpieza general } Qué es el FilterConfig? Qué es el FilterChain? [Capítulo 5] Página 68

69 FILTROS INTERFAZ FilterConfig Bueno, como se menciona en el titulo... FilterConfig es una interfaz, la cual provee parámetros de inicialización para el filtro. Es similar al ServletConfig del servlet. Declara 4 métodos: MÉTODO DESCRIPCIÓN String getfiltername() Regresa el nombre del filtro especificado en el DD (web.xml). String getinitparameter(string) Regresa el valor del parámetro especificado en el DD (web.xml). Enumeration getinitparameternames() Regresa los nombres de todos los parámetros especificados en el DD (web.xml). ServletContext getservletcontext() Regresa el objeto SevletContext asociado con esta aplicación web. Los filtros lo pueden usar para obtener y fijar atributos con ámbito o alcance de aplicación. Los filtros así como los servlets tienen parámetros iniciales Así es, los filtros tienen parámetros iniciales o parámetros de inicialización. Estos parámetros son declarados en el DD (web.xml) en forma de pares de cadenas (strings) nombre/valor. Ya en el filtro uno solicita el nombre y el resultado obtenido es el valor. De esta forma el nombre permanece invariable en el código del filtro y ya en el DD nosotros tenemos la posibilidad de modificar el valor cuando se requiera. [Capítulo 5] Página 69

70 FILTROS INTERFAZ FilterChain Bueno, como se menciona en el titulo... FilterChain es una interfaz que los filtros usan para invocar al siguiente filtro que se encuentra en la cadena o si el filtro invocado fuera el ultimo de la cadena entonces invocaría al recurso. Tiene un solo método: dofilter(servletrequest, ServletResponse) Los filtros son modulares y se configuran en el DD (web.xml). Lo que quiere decir con modulares es que pueden ser encadenados, esto es, se pueden configurar en el DD (web.xml) para que se ejecuten uno detrás de otro como cadena Por ejemplo, en la imagen de arriba se ejecutan los filtros 3, 6 y 9. Los filtros también son independientes, dueños de sí mismos, lo que significa que no les interesa si hay otro filtro antes o después de él. Esto también nos dicta que al crear el código de un filtro NO LO DEBEMOS HACER DEPENDIENTE DE OTRO, NO DEBEMOS CREAR DEPENDENCIAS ENTRE FILTROS. Si creáramos dependencias entre filtros estaríamos corrompiendo la esencia del filtro. Aquí es donde entra FilterChain. FilterChain es el objeto qué sabe qué filtro sigue en la cadena. FilterChain sabe el orden de ejecución de los filtros. Y lo hace basándose en la configuración del DD (web.xml). [Capítulo 5] Página 70

71 FILTROS DECLARAR UN FILTRO Para poder declarar un filtro necesitas la clase que implemente la interfaz Filter y después declararlo en el DD (web.xml). Veamos un ejemplo de un filtro que obtenga el puerto del cliente. Clase: package com.filters; import java.io.ioexception; import javax.servlet.filter; import javax.servlet.filterchain; import javax.servlet.filterconfig; import javax.servlet.servletexception; import javax.servlet.servletrequest; import javax.servlet.servletresponse; import javax.servlet.http.httpservletrequest; public class ClientPortFilter implements Filter { private FilterConfig config; public void init(filterconfig config) throws ServletException { this.config = config; } public void dofilter(servletrequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException { HttpServletRequest httprequest = (HttpServletRequest)request; int clientport = httprequest.getremoteport(); } System.out.println("clientPort: " + clientport); } public void destroy() { } [Capítulo 5] Página 71

72 FILTROS DD (web.xml): <web-app...>... <filter> <filter-name>clientportfilter</filter-name> <filter-class>com.filters.clientportfilter</filter-class> </filter> <filter-mapping> <filter-name>clientportfilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>... </web-app> SALIDA OBTENIDA: clientport: 2507 clientport: 2512 [Capítulo 5] Página 72

73 OYENTES (LISTENERS) Capítulo 6 OYENTES (LISTENERS) [Capítulo 6] Página 73

74 OYENTES (LISTENERS) QUE ES UN OYENTE (LISTENER)? Como observamos en el capítulo de atributos, nosotros podemos obtener parámetros iniciales pero éstos solo pueden ser Strings. Qué tal si quisiéramos obtener un parámetro inicial que no fuera un String? Qué tal si quisiéramos, por ejemplo, que toda la aplicación compartiera una conexión a una base de datos? Por supuesto puedes poner el nombre de un DataSource en un <context-param>, pero... y luego... Quién realiza el trabajo de convertir ese parámetro String en un objeto DataSource que todos puedan compartir dentro de la aplicación web? No puedes poner este código en un servlet porque... Cuál servlet escogerías que fuera el que hiciera el lookup al DataSource? Realmente quieres garantizar que un servlet siempre corriera primero? Entonces lo que necesitas es un Listener. Necesitas un Oyente (alguien que escuche) para un evento de inicialización de contexto para que este objeto sea creado y compartido por todos antes que el resto de la aplicación pueda servir a algún cliente. Necesitas un ServletContextListener para el caso anterior. Pero existen ocho de los cuales puedes echar mano dependiendo de lo que necesites. [Capítulo 6] Página 74

75 OYENTES (LISTENERS) LOS OCHO GRANDES 1. ServletContextListener 2. ServletContextAttributeListener 3. ServletRequestListener 4. ServletRequestAttributeListener 5. HttpSessionListener 6. HttpSessionBindingListener 7. HttpSessionAttributeListener 8. HttpSessionActivationListener Interfaz ServletContextListener <<interface>> javax.servlet.servletcontextlistener void...contextinitialized(javax.servlet.servletcontextevent) void...contextdestroyed(javax.servlet.servletcontextevent) Interfaz ServletContextAttributeListener <<interface>> javax.servlet.servletcontextattributelistener void...attributeadded(javax.servlet.servletcontextattributeevent) void....attributeremoved(javax.servlet. ServletContextAttributeEvent) void...attributereplaced(javax.servlet. ServletContextAttributeEvent) Interfaz ServletRequestListener <<interface>> javax.servlet.servletrequestlistener void.requestinitialized(javax.servlet.servletrequestevent) void.requestdestroyed(javax.servlet.servletrequestevent) [Capítulo 6] Página 75

76 OYENTES (LISTENERS) Interfaz ServletRequetAttributeListener <<interface>> javax.servlet.servletrequestattributelistener void.attributeadded(javax.servlet.servletcontextattributeevent) void.attributeremoved(javax.servlet. ServletContextAttributeEvent) void.attributereplaced(javax.servlet. ServletContextAttributeEvent) Interfaz HttpSessionListener <<interface>> javax.servlet.http.httpsessionlistener void.sessioncreated(javax.servlet.http.httpsessionevent) void.sessiondestroyed(javax.servlet.http.httpsessionevent) Interfaz HttpSessionBindingListener <<interface>> javax.servlet.http.httpsessionbindinglistener void...valuebound(javax.servlet.http.httpsessionbindingevent) void.valueunbound(javax.servlet.http.httpsessionbindingevent) Interfaz HttpSessionAttributeListener <<interface>> javax.servlet.http.httpsessionbindinglistener void.attributeadded(javax.servlet.http.httpsessionbindingevent) void.attributeremoved(javax.servlet.http.httpsessionbindingevent) void.attributereplaced(javax.servlet.http.httpsessionbindingevent) Interfase HttpSessionActivationListener Interfaz HttpSessionActivationListener <<interface>> javax.servlet.http.httpsessionactivationlistener void.sessionwillpassivate(javax.servlet.http.httpsessionevent) void.sessiondidactivate(javax.servlet.http.httpsessionevent) [Capítulo 6] Página 76

77 OYENTES (LISTENERS) EJERCICIO A continuación voy a poner diferentes escenarios y tu misión será determinar cual Listener es el adecuado a utilizar de acuerdo al nombre del Listener mencionado arriba y a los métodos. Esto es bastante intuitivo, por eso quiero que lo hagas tú mismo. Escenario 1: Quieres saber si un atributo en un contexto de una aplicación web ha sido agregado, quitado o reemplazado. Escenario 2: Quieres saber cuantos usuarios concurrentes hay. En otras palabras, quieres llevar el seguimiento de las sesiones activas. Escenario 3: Quieres saber cuando llega una petición para que puedas loggearla. Escenario 4: Quieres saber cuando un atributo de petición ha sido agregado, quitado o reemplazado. Escenario 5: Tienes una clase que representa un atributo y quieres que objetos de este tipo sean notificados cuando son ligados o quitados de una sesión. Escenario 6: Quieres saber cuando un atributo de sesión ha sido agregado, quitado o reemplazado. Escenario 7: Quieres saber si un contexto ha sido creado o destruido. Escenario 8: Tienes un una clase que representa un atributo y quieres que objetos de ese tipo sean notificados cuando la sesión a la que están ligados se esta migrando a otra Maquina Virtual de Java (JVM). [Capítulo 6] Página 77

78 OYENTES (LISTENERS) SOLUCION AL EJERCICIO: Escenario 1: ServletContextAttributeListener Escenario 2: HttpSessionListener Escenario 3: ServletRequestListener Escenario 4: ServletRequestAttributeListener Escenario 5: HttpSessionBindingListener Escenario 6: HttpSessionAttributeListener Escenario 7: ServletContextListener Escenario 8: HttpSessionActivationListener [Capítulo 6] Página 78

79 OYENTES (LISTENERS) EJEMPLO: Vamos a ver un ejemplo práctico para ver como se aplica un Listener. Supongamos que queremos compartir un DataSource en toda la aplicación y que este se encuentre disponible antes que el resto de la aplicación pueda servir a algún cliente. Listener: import javax.naming.context; import javax.naming.initialcontext; import javax.naming.namingexception; import javax.servlet.servletcontext; import javax.servlet.servletcontextevent; import javax.servlet.servletcontextlistener; import javax.sql.datasource; public class DataSourceListener implements ServletContextListener { public void contextinitialized(servletcontextevent event) { ServletContext sc = event.getservletcontext(); try { // Codigo para obtener el DataSource Context ctx = new InitialContext(); String nombreds = sc.getinitparameter("datasource"); DataSource ds = (DataSource)ctx.lookup(nombreDS); } if (ds!= null) { // Codigo para almacenar el DataSource como atributo sc.setattribute("datasource", ds); } } catch (NamingException ex) { ex.printstacktrace(); } } public void contextdestroyed(servletcontextevent event) { // Codigo para limpiar objetos ServletContext sc = event.getservletcontext(); sc.removeattribute("datasource"); } [Capítulo 6] Página 79

80 OYENTES (LISTENERS) DD (web.xml): <web-app...>... <listener> <servlet-class>datasourcelistener</servlet-class> </listener> <context-param> <param-name>datasource</param-name> <param-value>midatasource</param-value> </cotext-param>... </web-app> Servlet: import java.io.ioexception; import java.sql.connection; import javax.servlet.servletcontext; import javax.servlet.servletexception; import javax.servlet.http.httpservlet; import javax.servlet.http.httpservletrequest; import javax.servlet.http.httpservletresponse; import javax.sql.datasource; public class DataSourceServlet extends HttpServlet { public void dopost(httpservletrequest request, HttpServletResponse response) throws IOException, ServletException { ServletContext ctx = getservletcontext(); DataSource ds = (DataSource)ctx.getAttribute("dataSource"); } } // Aqui podemos obtener la conexión y demás... //Connection conn = ds.getconnection(); [Capítulo 6] Página 80

81 LA SESION Capítulo 7 LA SESION [Capítulo 7] Página 81

82 LA SESION OBJETIVOS DEL EXAMEN Sección 4: Administración de la Sesión Escribe código de servlet para almacenar objetos dentro de un objeto de sesión y recupera objetos desde un objeto de sesión. Dado un escenario describe las APIs usadas para acceder al objeto de sesión, explica cuando el objeto de sesión fue creado y describe los mecanismos usados para destruir al objeto de sesión y cuando fue destruido. Usando los oyentes de sesión, escribe código que responda a un evento cuando un objeto es agregado a una sesión y escribe código que responda a un evento cuando un objeto de sesión migra de una máquina virtual (VM) a otra. Dado un escenario, describe que mecanismo de administración de sesiones podría emplear el contenedor web, como se pueden usar las cookies para administrar las sesiones, como URL rewriting podría ser usado para administrar sesiones y escribir código de servlet para realizar URL rewriting. [Capítulo 7] Página 82

83 LA SESION INTRODUCCIÓN Las aplicaciones web generalmente interactúan con más de un usuario a la vez y en algunas ocasiones es necesario recordar a cada uno de ellos. Ya que todas las peticiones son independientes y no están relacionadas, el servidor no tiene una forma de determinar si una serie de peticiones proviene del mismo cliente o de diferentes. Esto significa que el servidor no puede mantener un estado conversacional entre múltiples peticiones, en otras palabras el servidor no recuerda al cliente. En algunas ocasiones es conveniente que el servidor no recuerde al cliente pero en otras no. La habilidad de un protocolo de recordar al usuario y sus peticiones se le llama estado. Y la sesión es la encargada de poder llevar a cabo este estado conversacional. Imagínate por ejemplo un carrito de compras, el usuario quiere agregar o quitar artículos, no sería muy amigable por parte de la aplicación que al momento de que el cliente solicitara la lista de artículos que tiene en su carrito de compras le dijera: lo siento lo olvidé por completo. Para llevar a cabo lo anterior el servidor debe tener la posibilidad de llevar el seguimiento de los artículos agregados o removidos del carrito. [Capítulo 7] Página 83

84 LA SESION Cómo se intercambia información de sesión entre cliente y servidor? La forma más común y simple de intercambiar información es por medio de cookies. El servidor envía la cookie con el ID de sesión. HTTP/ OK Set-Cookie: JSESSIONID=0AAC6C6DE123 Content-Type: text/html Content-Length: 666 Date: Wed, 24 Nov :01:40 Server: Apache-Coyote/1.1 Connection: close <htlm>... </html> Cliente HTTP Response Servidor El cliente regresa la cookie con la petición. POST /select/selectbeer.do HTTP/1.1 Host: User-Agent: Mozilla/5.0 Cookie: JSESSIONID=0AAC6C6DE123 Accept: text/html,application/xhtml HTTP Request Servidor Cliente [Capítulo 7] Página 84

85 LA SESION Quién realiza todo el trabajo al usar cookies? El Contenedor. Tú le tienes que decir al Contenedor que quieres crear o usar una sesión, pero el Contenedor se ocupa de: Generar el ID de sesión Crear un nuevo objeto Cookie Pegar el ID de sesión en la cookie Fijar la cookie como parte de la respuesta Y en peticiones subsecuentes, el Contenedor obtiene el ID de la sesión de la cookie que viene en la petición, compara el ID de la sesión con la sesión existente y asocia esa sesión con la petición actual. ENVIAR UNA COOKIE DE SESIÓN EN LA RESPUESTA HttpSession session = request.getsesion(); Eso es todo. En algún lado en tu método service() solicitas una sesión y todo lo demás sucede automáticamente. Tú no haces el nuevo objeto HttpSession. Tu no generas el único ID de sesión. Tú no haces el nuevo objeto Cookie. Tu no asocias el ID de sesión con la cookie. Tú no fijas el Cookie en la respuesta (bajo el encabezado Set-Cookie). Todo el trabajo se realiza detrás de escena. Ahora nadie garantiza que el cliente acepte las cookies... [Capítulo 7] Página 85

86 LA SESION OBTENER EL ID DE SESIÓN DE LA PETICIÓN HttpSession session = request.getsesion(); Igual que enviar una cookie de sesión en la respuesta? Sí. Exactamente igual. Todo el trabajo relacionado a las cookies pasa detrás de escena. Pero a ver un momento!!! Quién hace qué cosas? Qué son las cookies? Qué pasa si el cliente no acepta cookies?... RESPUESTA: Bueno... primero como se dijo, la forma más común y sencilla de intercambiar información entre un cliente y un servidor es por medio de cookies. Una cookie es un fragmento de información que se almacena en el disco duro del cliente por medio del navegador. Esta información puede ser luego recuperada por el servidor. Las inventó Lou Montulli un empleado de Netscape Communications. Lo anterior es por si querías saberlo pero no viene en el examen. De aquí surge el siguiente razonamiento... si nadie garantiza que el cliente acepte cookies entonces Qué se hace? [Capítulo 7] Página 86

87 LA SESION Métodos del objeto Cookie Cookie(String, String) <<interface>> javax.servlet.http.cookie String..getDomain() int. getmaxage() String..getName() String..getPath() boolean..getsecure() String..getValue() void.setdomain(string) void. setmaxage(string) void. setpath(sring) void. setvalue(string) // Más métodos Cuánto tiempo vive una cookie? Por default, una cookie vive el tiempo que dura la sesión. Una vez que el cliente sale del navegador la cookie desaparece. Así es como JSESSIONID trabaja. Pero tú puedes decirle a la cookie que se mantenga viva aun después de salir del navegador. Puedes usar las cookies para otras cosas o solo se usan para sesiones? Tú puedes usar cookies para intercambiar pares de strings nombre/valor entre el servidor y el cliente. Cómo creas una cookie? Cookie cookie = new Cookie("username", name); Cómo fijas el tiempo de duración de una cookie en el cliente? cookie.setmaxage(30 * 60); setmaxage() está definido en segundos. El código dice: vive en el cliente por 30*60 segundos (30 minutos). [Capítulo 7] Página 87

88 LA SESION NOTA: Poner setmaxage(-1), hace que la cookie desaparezca cuando se sale del navegador. Así, si llamas a getmaxage() en la cookie JSESSIONID... Qué obtendrías? Exacto Cómo envías la cookie al cliente? response.addcookie(cookie); Cómo obtienes la cookie de la petición cliente? Cookie[] cookies = request.gecookies(); for (int i = 0; i < cookies.length; i++) { Cookie cookie = cookies[i]; } if (cookie.getname().equals(("username")) { String username = cookie.getvalue(); out.println("hola " + username); break; } No existe un método getcookie(string), solo puedes obtener el arreglo de cookies y hacer el ciclo de ese arreglo para encontrar lo que quieres. Qué tal si quiero saber si la sesión ya existía o fue creada? El método sin argumento getsession() regresa un HttpSession sin importar si existe o no. Así que la única forma de saber si la sesión es nueva o no es preguntándole a la sesión. [Capítulo 7] Página 88

89 LA SESION COMO SE VE EN CÓDIGO: import java.io.ioexception; import java.io.printwriter; import javax.servlet.servletexception; import javax.servlet.http.httpservlet; import javax.servlet.http.httpservletrequest; import javax.servlet.http.httpservletresponse; import javax.servlet.http.httpsession; public class ServletNuevaSesion extends HttpServlet { public void doget(httpservletrequest request, HttpServletResponse response) throws ServletException, IOException { response.setcontenttype("text/html"); PrintWriter out = response.getwriter(); HttpSession session = request.getsession(); } } if (session.isnew()) { out.println("esta sesion es NUEVA..."); } else { out.println("de regreso a la sesion EXISTENTE..."); } El método isnew() regresa true si el cliente no corresponde al ID de sesión. Qué tal si quiero únicamente una sesión preexistente? Hay un método sobrecargado de getsession() que recibe de argumento un bolean: getsession(boolean). En este caso si tu no quisieras crear una nueva sesión entonces llamarías a getsession(false) y obtendrías la sesión preexistente o null en caso contrario. [Capítulo 7] Página 89

90 LA SESION COMO SE VE EN CÓDIGO: import java.io.ioexception; import java.io.printwriter; import javax.servlet.servletexception; import javax.servlet.http.httpservlet; import javax.servlet.http.httpservletrequest; import javax.servlet.http.httpservletresponse; import javax.servlet.http.httpsession; public class ServletSesionPreexistente extends HttpServlet { public void doget(httpservletrequest request, HttpServletResponse response) throws ServletException, IOException { response.setcontenttype("text/html"); PrintWriter out = response.getwriter(); HttpSession session = request.getsession(false); } } if (session == null) { out.println("no existe ninguna sesión..."); } else { out.println("de regreso a la sesion PREEXISTENTE..."); } Pasar false de argumento en el método significa que regresa una sesión preexistente o null si no hay ninguna sesión asociada con este cliente. Arriba se obtuvo una sesión llamando a request.getsession(), pero la pregunta sería: Es la única forma de obtener una sesión? No se podría hacer por ejemplo con el ServletContext? La sesión es identificada por la petición. La sesión es para el cliente asociado con esta petición. Pero hay otra forma de obtener una sesión... de un objeto de evento de sesión. Recuerdas los Listeners... no son servlets ni JSPs, es solo una clase que quiere saber sobre eventos. [Capítulo 7] Página 90

91 LA SESION Por ejemplo, el Listener podría ser un atributo tratando de saber cuando fue agregado a o quitado de una sesión. Los métodos definidos por las interfaces Listener para el manejo de eventos toman un argumento de tipo HttpSessionEvent o su subclase HttpSessionBindingEvent. Y resulta que HttpSessionEvent tiene un método getsession(). Así que si implementas cualquiera de las cuatro interfaces Listener relacionadas a la sesión, puedes tener acceso a la sesión por medio del método que maneja el evento. Ejemplo de un fragmento de código: import javax.servlet.http.httpsession; import javax.servlet.http.httpsessionevent; import javax.servlet.http.httpsessionlistener; public class PruebaListener implements HttpSessionListener { public void sessioncreated(httpsessionevent event) { HttpSession session = event.getsession(); // Más código... } } public void sessiondestroyed(httpsessionevent event) { HttpSession session = event.getsession(); // Más código... } En que casos se utiliza getsession(boolean)? Utilizas este método cuando no quieres crear una nueva sesión o cuando la decisión de crear una nueva sesión sucede en tiempo de ejecución (y pasas una variable dentro del método getsession(var)). [Capítulo 7] Página 91

92 LA SESION Bueno ahora si por piedad contesta Qué se hace si el cliente no acepta las cookies? Cómo creas la sesión sin cookies? Creo que ya fue mucho castigo para este cuate, a este paso no va a conocer nunca la respuesta. Contéstele alguien por piedad... O va a perder la cabeza Para estos casos donde el cliente no acepta cookies y tu llamas a getsession() en la petición, el Contenedor trata de usar cookies. Y si las cookies no están habilitadas significa que el cliente nunca se unirá a la sesión. Esto es, el método isnew() siempre regresara true. Un cliente con las cookies deshabilitadas va a ignorar el encabezado Set-Cookie de la respuesta. Si el cliente no acepta las cookies no va a obtener una excepción. Solo significa que el cliente ignora el intento de fijar una cookie con el ID de la sesión. [Capítulo 7] Página 92

93 LA SESION Bueno ya estuvo suave... ya dime!!!! Qué se hace? Bueno, puedes usar URL rewriting como un mecanismo de respaldo. URL rewriting siempre funcionará. URL rewriting toma el ID de la sesión que se encuentra en la cookie y la pega justo al final de cada URL que viene en la aplicación. URL + ;JSESSIONID= Yupiiii! Por fin me contestaron. Aunque me siento más delgado [Capítulo 7] Página 93

94 LA SESION HTTP Response HTTP/ OK Content-Type: text/html Content-Length: 666 Date: Wed, 24 Nov :01:40 Server: Apache-Coyote/1.1 Connection: close <html> <body> <a href= Da clic </a> </body> </html> HTTP Request GET /prueba.do;jsessionid= HTTP/1.1 Host: User-Agent: Mozilla/5.0 Accept: text/html,application/xhtml El ID de sesión regresa con información extra pegada al final del URL de la petición. El punto y coma (;) sirve como separador y es especifico de cada vendedor. URL rewriting sirve solo si las cookies fallan y solo si le dices a la respuesta que codifique la URL. El Contenedor por default siempre usa cookies primero y como última opción URL rewriting. Si explícitamente no codificas tus URLs y el cliente no acepta cookies entonces no debes usar sesiones. [Capítulo 7] Página 94

95 LA SESION Ejemplo: public void doget(httpservletrequest request, HttpServletResponse response) throws ServletException, IOException { response.setcontenttype("text/html"); HttpSession session = request.getsession(); } PrintWriter out = response.getwriter(); out.println("<html><body>"); out.println("<a href=\"" + response.encodeurl("/prueba.do") + "\">clic</a>"); out.println("</body></html>"); Cómo sabe el Contenedor que las cookies no están trabajando? Y en qué momento decide utilizar URL rewriting? Un Contenedor malo no le importa si trabajan o no las cookies, siempre intentará enviar la cookie y hacer URL rewriting todo el tiempo aún si las cookies trabajan. Pero un Contenedor decente cuando ve un llamado a getsession() y el Contenedor no obtiene un ID de sesión con la petición del cliente, el Contenedor ahora sabe que debe intentar iniciar una nueva sesión con el cliente, el Contenedor envía la respuesta con ambos un encabezado Set-Cookie para el ID de la sesión y el ID de la sesión anexado a las URLs (asumiendo que usaste response.encodeurl()). En este punto el Contenedor no sabe si las cookies van a funcionar, así que con esta primer respuesta que regresa al cliente, trata ambos cookies y URL rewriting. Ahora imagina la siguiente petición de este cliente, tendrá el ID de la sesión anexado a la URL, pero si el cliente acepta cookies la petición también tendrá una cookie de sesión. Cuando se llama a getsession() el Contenedor lee el ID de la sesión de la petición, encuentra la sesión y se dice a sí mismo Este cliente acepta cookies, así que puedo ignorar el llamado response.encodeurl(). En la respuesta, enviaré una cookie ahora que se que funcionan y o hay necesidad de URL rewriting. [Capítulo 7] Página 95

96 LA SESION URL rewriting y sendredirect() Podrías tener un escenario donde quieras redireccionar la petición a un URL diferente y que aun quieras seguir usando una sesión. Para este caso existe un método: response.encoderedirecturl( /Prueba.do ); URL encoding es manejado por la respuesta. No olvides que encodeurl() es un método que llamas en tu objeto HttpServletResponse. No lo llamas de la petición o de tu contexto o de tu sesión. Puedes usar URL rewriting en paginas HTML estáticas? No. La única forma de usar URL rewriting es si todas las paginas que son parte de la sesión son generadas dinámicamente. Tu no puedes hardcodear IDs de sesión obviamente, ya que el ID no existe hasta el tiempo de ejecución. Así que si dependes de sesiones necesitas URL rewriting como una estrategia de respaldo. Y ya que necesitas URL rewriting tienes que generar dinámicamente las URLs en el HTML de respuesta. Y eso significa que tienes que procesar el HTML en tiempo de ejecución. Y sí existe un problema de desempeño. Esto significa también que URL rewriting se puede usar en las JSPs. Es URL rewriting manejado de una forma especifica de cada vendedor? Sí. Tomcat por ejemplo usa ; para anexar la información extra al URL. [Capítulo 7] Página 96

97 LA SESION Interfaz HttpSession <<interface>> javax.servlet.http.httsession Object.. getattribute(string) void.. setattribute(string, Object) void.. removeattribute(string) long.. getcreationtime() String...getId() long...getlastaccesedtime() int. getmaxinactiveinterval() ServletContext..getServletContext() void.invalidate() boolean..isnew() void.setmaxinactiveinterval(int) // más métodos 3 Formas de matar la sesión 1. Expira su tiempo 2. Llamar al método invalidate() en el objeto de sesión. 3. Se cae la aplicación (falla el sistema o se quita el despliegue (undeploy)). Configurar el timeout de la sesión en el DD <web-app...> <session-config> <session-timeout>13</ session-timeout > </session-config> </web-app> El valor de <session-timeout> esta en minutos. Esto es, 13 minutos es el tiempo en que la sesión expira. Configurar el timeout de la sesión de forma programática session.setmaxinactiveinterval(13 * 60); Este tiempo esta en segundos. Donde: 13 * 60 = 780 segundos = 13 minutos [Capítulo 7] Página 97

98 JSP Capítulo 8 JSP [Capítulo 8] Página 98

99 JSP INTRODUCCIÓN Java Server Pages (JSP), es una tecnología J2EE que permite a los Desarrolladores de Software generar contenido web dinámico tales como páginas HTML, DHTML, XHTML y XML. Esta tecnología permite embeber código java dentro del contenido estático (lo cual como veremos más adelante no es recomendable, mejor dicho es una pesadilla). La versión de la especificación que a continuación vamos a ver es la 2.0. FASES DE UNA JSP Hay 2 fases en el ciclo de vida de una JSP: 1. Traducción 2. Ejecución En la fase de traducción, el Contendor valida que la sintaxis sea correcta. En la fase de ejecución el Contenedor administra las instancias de esta clase. Al final de cuentas la JSP se convierte en un servlet. La diferencia reside en que cuando haces un servlet, tú mismo realizas el código. Pero para el caso de una JSP todo lo que se encuentra dentro de ella es traducido a código fuente por el Contenedor (archivo.java). Más tarde este código es compilado (archivo.class). Finalmente se convierte en servlet. Esto es, el Contenedor lo carga, crea la instancia, lo inicializa, crea un hilo (thread) por cada petición y llama al método service() del servlet. Se escribe Se traduce Se compila Se carga e inicializa MiJSP.jsp MiJSP_jsp.java MiJSP_jsp.class MiJSP_jsp Servlet [Capítulo 8] Página 99

100 JSP ELEMENTOS DE UNA JSP Directivas Scripts Acciones DIRECTIVAS Proveen información en tiempo de traducción a la JSP. Las directivas NO producen ninguna salida visible en la JSP. Su sintaxis es de la siguiente forma: <%@ directiva... lista_de_atributos %> Arriba me dices lo que hace una directiva pero no lo que es Una directiva es un acto normativo. Norma: Toda regla de conducta de observancia obligatoria. Parece que estamos en la clase de Derecho No somos abogansters [Capítulo 8] Página 100

101 JSP Es cierto, parece una definición para Derecho, pero si la desglosamos por partes veremos que se asemeja a la definición que necesitamos. La directiva es un acto, un hecho, algo que le dice a la JSP lo que debe tener (lo que debe tener es la regla) para poder traducirse correctamente en servlet (para hacerlo correctamente implica que lo obliga a...). Recordemos que las directivas le dan información a la JSP en tiempo de traducción, esto es, antes de ser convertidas a servlet y antes de ser código java como lo vimos en las fases. Por lo tanto, si una JSP omite alguna directiva que necesite simplemente no podrá ser compilada. Existen las siguientes directivas: page include taglib Directiva page Le da al Contenedor información que necesita cuando traduce la JSP en servlet. Existen 13 atributos para esta directiva: import El resultado es un import de java. Por default se obtienen los siguientes: java.lang javax.servlet javax.servlet.http javax.servlet.jsp [Capítulo 8] Página 101

102 JSP isthreadsafe Define si el servlet generado necesita implementar el SingleThreadModel. El valor por default es true, lo que significa que la aplicación es thread safe (segura de hilos de ejecución), así que no se necesita implementar el SingleThreadModel. contenttype Especifica el contenido que es generado. Se debe utilizar en caso de que HTML no se use o si el carácter de codificación no es el de default. iselignored Define si las expresiones EL serán ignoradas cuando la JSP sea traducida. iserrorpage Define si la página actual es una página de error. El valor por default es false. Si se pone en true, la página tendrá acceso al objeto implícito de excepción (el cual es una referencia a Throwable). Si es false no tendrá acceso a este objeto. errorpage Indica la pagina que será mostrada si ocurre una excepción mientras se procesa una petición HTTP. language Define el lenguaje de script usado en scriptlets, expressions y declarations. Por el momento, el único posible valor es java. extends Define la superclase de la clase a la que esta JSP llegara a ser. Sobrescribe la jerarquía de clases que provee el Contenedor. [Capítulo 8] Página 102

103 JSP session Define si la página tendrá un objeto implícito de sesión. El valor por default es true. buffer Es para fijar el tamaño del buffer. El valor por default es 8kb. En caso de no requerir buffer entonces se debe poner el valor de none. autoflush Define si la salida con buffer será vaciada automáticamente. El valor por default es true. Es ilegal y resulta en un error de traducción fijar autoflush= false cuando buffer= none. info Define un string arbitrario que es incorporado dentro de la página traducida, que subsecuentemente puede ser obtenido desde la implementación de la página del método getservletinfo() de la interfaz Servlet. pageencoding Define la codificación de caracteres para la página JSP. El valor por default es ISO (a menos que el atributo contenttype ya haya definido una codificación de caracteres o que la página use la sintaxis de Documento XML). [Capítulo 8] Página 103

104 JSP Sintaxis page lista_de_atributos %> lista_de_atributos: { import= listadeimports } { isthreadsafe= true false } { contenttype= infotipocontenido } { iselignored= true false } { iserrorpage= true false } { errorpage= errorurl } { language= lenguajescript } { extends= nombreclase } { session= true false } { buffer= none tamañoenkb } { autoflush= true false } { info= infotexto } { pageencoding= infocodificacion } En muchos libros y bibliografía referente a JSP no se especifica si la directiva page va con espacio o va junto y visualmente es muy difícil observarlo claramente. Bueno pues puede ir de las 2 formas (con o sin espacios, es a gusto del cliente). Lo siguiente es correcto: <%@page lista_de_atributos %> <%@ page lista_de_atributos %> <%@ page lista_de_atributos %> sin espacio con un espacio con dos espacios Ejemplo: <%@ page language= java import= com.test.* buffer= 16kb %> [Capítulo 8] Página 104

105 JSP Directiva include La directiva include es usada para sustituir texto y/o código en tiempo de traducción de la página JSP. En otras palabras informa al compilador de la JSP que incluya un archivo completo dentro del archivo original. Sintaxis include file="url_relativo" %> Ejemplo: include file="titulo.html" %> Directiva taglib La directiva taglib indica que una librería de etiquetas (tags) JSP va a ser usada. Sintaxis <%@ taglib prefix= tagprefix (uri= taglibraryuri tagdir= tagdir ) %> Ejemplo: <%@ taglib prefix= cool uri= RAC %> <%@ taglib prefix= cool tagdir= /WEB-INF/tags %> Donde: prefix: Define el prefijo que será usado para distinguir una acción personalizada, por ejemplo: <cool:mitag> [Capítulo 8] Página 105

106 JSP Las siguientes son palabras reservadas y no se pueden usar como prefijos: jsp jspx java javax servlet sun sunw Un prefijo debe seguir la convención de nombres especificada en XML. Los prefijos vacíos no son válidos para esta versión y resultan en un error de traducción. uri: Puede ser un URI absoluto o relativo que identifica de forma única el descriptor de la librería de tags asociada con este prefijo. tagdir: Le indica a este prefijo que será usado para identificar extensiones de tags instaladas dentro del directorio /WEB- INF/tags/ o cualquier subdirectorio. Si se usa junto con el atributo uri ocurrirá un error de traducción. También habrá un error de traducción si el valor apunta a un directorio que no exista. [Capítulo 8] Página 106

107 JSP SCRIPTS Estos elementos proveen una especie de unión entre texto y acciones. ELEMENTOS 1. Scriptlet 2. Expression 3. Declaration Scriptlet Un scriptlet es un tag dentro del cual puedes introducir código java. Sintaxis <% scriptlet %> Ejemplo: Se puede declarar una variable local dentro del scriptlet. <% int i = 0; %> <% i++; %> <% out.println(i); %> Expression Un expression es un script que es evaluado y el resultado es convertido a String. Automáticamente imprime lo que se encuentra dentro de sus tags. Las expression no deben terminar con el punto y coma (;). Las expression vienen a ser el argumento de out.print(). En otras palabras, todo lo que pongas dentro de <%=... %> va a ser el argumento de out.print(...). Sintaxis <%= expression %> [Capítulo 8] Página 107

108 JSP En el tag inicial el signo de porcentaje (%) y el signo igual (=) van juntos, no llevan espacios. Ejemplo: <%= i %> out.print(i); <%= new java.util.date() %> out.print(new java.util.date()); <%= i++; %> out.print(i++;) Esto es inválido por el punto y coma (;). Declaration Declara y define variables y métodos dentro del cuerpo de la clase servlet, esto es, al mismo nivel del método service(). Lo hace global a la página. No producen ninguna salida. Son inicializadas cuando la página JSP es inicializada. Sintaxis <%! declaration(s) %> Ejemplos: <%! int i = 0; %> <%! %> public String getname() { return ABI ; } [Capítulo 8] Página 108

109 JSP Vamos a ver lo que produce la siguiente JSP: <html> <body> <%! int i = 0; %> El valor de i es: <%= ++i %> </body> </html> El servlet generado por Tomcat: package org.apache.jsp; import javax.servlet.*; import javax.servlet.http.*; import javax.servlet.jsp.*; public final class ServletGeneradoPorTomcat_jsp extends org.apache.jasper.runtime.httpjspbase implements org.apache.jasper.runtime.jspsourcedependent { int i = 0; private static final JspFactory _jspxfactory = JspFactory.getDefaultFactory(); private static java.util.list _jspx_dependants; private javax.el.expressionfactory _el_expressionfactory; private org.apache.annotationprocessor _jsp_annotationprocessor; public Object getdependants() { return _jspx_dependants; } public void _jspinit() { _el_expressionfactory = _jspxfactory.getjspapplicationcontext(getservletconfig(). getservletcontext()).getexpressionfactory(); _jsp_annotationprocessor = (org.apache.annotationprocessor) getservletconfig().getservletcontext().getattribute(org.apache. AnnotationProcessor.class.getName()); } public void _jspdestroy() { } public void _jspservice(httpservletrequest request, HttpServletResponse response) throws java.io.ioexception, ServletException { PageContext pagecontext = null; [Capítulo 8] Página 109

110 JSP } } HttpSession session = null; ServletContext application = null; ServletConfig config = null; JspWriter out = null; Object page = this; JspWriter _jspx_out = null; PageContext _jspx_page_context = null; try { response.setcontenttype("text/html"); pagecontext = _jspxfactory.getpagecontext(this, request, response, null, true, 8192, true); _jspx_page_context = pagecontext; application = pagecontext.getservletcontext(); config = pagecontext.getservletconfig(); session = pagecontext.getsession(); out = pagecontext.getout(); _jspx_out = out; out.write("<html>\n"); out.write("\t<body>\n"); out.write("\t\t"); out.write("\r\n"); out.write("\t\tel valor de i es:\r\n"); out.write("\t\t"); out.print(++i); out.write("\n"); out.write("\t</body>\n"); out.write("</html>"); } catch (Throwable t) { if (!(t instanceof SkipPageException)) { out = _jspx_out; if (out!= null && out.getbuffersize()!= 0) try { out.clearbuffer(); } catch (java.io.ioexception e) { } if (_jspx_page_context!= null) _jspx_page_context.handlepageexception(t); } } finally { _jspxfactory.releasepagecontext(_jspx_page_context); } [Capítulo 8] Página 110

111 JSP Podemos observar que de la declaration <%! int i = 0; %>, se obtiene una variable de instancia dentro de la clase ServletGeneradoPorTomcat, esto es: int i = 0; Y de la expression <%= ++i %>, se obtiene: out.print(++i); dentro del método _jspservice (...). ACCIONES Son etiquetas (tags) XML. Una acción puede ser estándar (definida en la especificación) o personalizada (por el mecanismo de extensión de etiquetas). Sintaxis <jsp:nombreaccion... lista_de_atributos /> ACCIONES ESTÁNDAR Las acciones estándar son representadas usando elementos XML con el prefijo jsp, aunque este prefijo puede ser redefinido en la sintaxis de XML. Se enviará un error de traducción si se utiliza el prefijo jsp para un elemento que no sea una acción estándar. Las siguientes son acciones estándar: jsp:usebean jsp:setproperty jsp:getproperty jsp:include jsp:forward jsp:plugin jsp:invoke jsp:dobody jsp:element jsp:output jsp:param [Capítulo 8] Página 111

112 JSP <jsp:usebean> Declara e inicializa un objeto bean. Y en caso de que no exista lo puede crear. Sintaxis Sin Cuerpo <jsp:usebean id="nombre" scope="page request session application" typespec /> Sintaxis Con Cuerpo <jsp:usebean id="nombre" scope="page request session application" typespec > cuerpo </jsp:usebean> Atributos de jsp:usebean id Es el nombre del identificador. Esto es, cuando se utiliza una clase llamada Empleado y la asignamos a emp: Empleado emp = new Empleado(); El identificador viene siendo emp y si esta clase tiene un método llamado getnombre(), lo podemos llamar así: emp.getnombre(); Por lo tanto, id= emp sería lo mismo. scope Nos indica el alcance que tendrá este objeto bean. El valor por default es page. typespec typespec => class= nombreclase class= nombreclase type= tiponombre type= tiponombre class= nombreclase beanname= nombrebean type= tiponombre type= tiponombre beanname= nombrebean type= tiponombre [Capítulo 8] Página 112

113 JSP class: Es el nombre completo de la clase, incluyendo el paquete en el que se encuentre. Ejemplo: com.prueba.beans.empleado class: Es el no beanname: Es el nombre de un bean. type: Define el tipo de la variable definida. type: Define Ejemplo: Código en el Bean: package com.prueba.beans; public class Empleado { private String nombre; public String getnombre() { return nombre; } } public void setnombre(string nombre) { this.nombre = nombre; } Código en el Servlet: public void dopost(httpservletrequest request, HttpServletResponse response) throws IOException, ServletException { } Empleado emp = new Empleado(); emp.setnombre("juan"); request.setattribute("empleado", emp); RequestDispatcher view = request.getrequestdispatcher("resultado.jsp"); view.forward(request, response); [Capítulo 8] Página 113

114 JSP Código en la JSP (con scripts): page import="com.prueba.beans.empleado" %> <html> <body> <% %> Empleado emp = (Empleado)request.getAttribute("empleado"); Empleado: <%= emp.getnombre() %> </body> </html> Código en la JSP (sin scripts): <html> <body> <jsp:usebean id="empleado" class="com.prueba.beans.empleado" scope="request" /> Empleado: <jsp:getproperty name="empleado" property="nombre" /> </body> </html> Resultado: Empleado: Juan [Capítulo 8] Página 114

115 JSP <jsp:setproperty> Fija los valores de propiedades en un bean. El atributo name que denota el bean debe ser definido antes de esta acción. Sintaxis: <jsp:setproperty name=" nombrebean " prop_expr /> prop_expr => property="*" property= nombrepropiedad property= nombrepropiedad param="nombreparametro" property= nombrepropiedad value= valorpropiedad valorpropiedad => string El valor valorpropiedad puede ser un valor de atributo de petición. Atributos de jsp:setproperty name property Es el nombre de la instancia del bean definido en la <jsp:usebean>. La instancia del bean debe contener la propiedad que se va a fijar. Es el nombre de la propiedad cuyo valor va a ser fijado. Si nombrepropiedad se pone como *, entonces el tag iterará sobre los parámetros de request encajando los nombres de los parámetros y tipos de valores con los nombres de las propiedades y tipos de métodos setters. Si el parámetro tiene un valor, la propiedad correspondiente no es modificada. [Capítulo 8] Página 115

116 JSP param value Es el nombre del parámetro de petición cuyo valor es dado a una propiedad del bean. El nombre del parámetro de petición generalmente proviene de un formulario web. Si param se omite el nombre del parámetro de petición se asume que es el mismo que el de la propiedad del bean. Si param no es fijado en el objeto de petición o si tiene el valor, la acción jsp:setproperty no tendrá efecto. Una acción no podrá tener ambos param y value. Es el valor que va a ser asignado a la propiedad. Este valor puede aceptar atributos de petición tal como una expresssion. Ejemplos: Las siguientes dos acciones fijan un valor proveniente de un parámetro de petición: <jsp:setproperty name= request property= * /> <jsp:setproperty name= user property= user param= username /> Los siguientes elementos fijan una propiedad proveniente de un valor: <jsp:setproperty name= results property= col value= ${i mod 4} /> <jsp:setproperty name= results property= row value= <%= i/4 %> /> [Capítulo 8] Página 116

117 JSP <jsp:getproperty> Esta acción pone el valor de la propiedad de una instancia del bean, convertida a String, dentro del objeto implícito out, cuyo valor puede ser desplegado como salida. La instancia del bean debe ser definida como se indicó en el atributo name vía la acción jsp:usebean. Sintaxis <jsp:getproperty name= name property= propertyname /> Atributos de jsp:getproperty name El nombre de la instancia del objeto del cual se obtiene la propiedad. property Nombre de la propiedad a obtener. Ejemplos: <jsp:getproperty name= user property= name /> <jsp:getproperty name= empleado property= nombre /> [Capítulo 8] Página 117

118 JSP COMENTARIOS Hay 2 tipos de comentarios en una JSP. 1. Comentarios propios de la JSP. Su sintaxis es la siguiente: <%-- comentarios... --%> Estos comentarios son tratados como una plantilla de texto no interpretado por el Contenedor. El contenido dinámico que aparece dentro de los comentarios, tales como acciones, scriptlets y expresiones lo sigue procesando el Contenedor. Si el comentario tiene datos dinámicos este puede ser obtenido con la sig. sintaxis: <!-- comments <%= expression %> more comments... --> 2. Comentarios de HTML, los cuales aparecen en la respuesta. Su sintaxis es la siguiente: <!-- comentarios... --> [Capítulo 8] Página 118

119 JSP EJEMPLO: Vamos a suponer que queremos mostrar en una JSP la fecha y la hora. Código en la clase Tiempo: package com.prueba.util; import java.text.dateformat; import java.util.calendar; import java.util.date; public class Tiempo { public static String getfecha() { Date d = new Date(); DateFormat df = DateFormat.getDateInstance(DateFormat.LONG); } return df.format(d); public static String gethora() { Date d = new Date(); Calendar calendar = Calendar.getInstance(); calendar.settime(d); } return "" + calendar.get(calendar.hour_of_day) + ":" + calendar.get(calendar.minute) + ":" + calendar.get(calendar.second) + " hrs."; } public static void main(string[] args) { System.out.println("Fecha: " + Tiempo.getFecha()); System.out.println("Hora: " + Tiempo.getHora()); } JSP: <html> <body> Fecha: <% out.println(com.prueba.util.tiempo.getfecha()); %> <br /> Hora: <% out.println(com.prueba.util.tiempo.gethora()); %> </body> </html> [Capítulo 8] Página 119

120 JSP Despliegue (Deploy): Dentro de webapps se crea el directorio tiempo y dentro de este se pone la JSP (tiempo.jsp). En este mismo directorio se crea otro llamado WEB-INF y dentro de este se crea otro llamado classes. Dentro del directorio classes se pone Tiempo.class. webapps tiempo WEB-INF tiempo.jsp classes web.xml Tiempo.class [Capítulo 8] Página 120

121 JSP Resultado: Si después de un tiempo y sin apagar el servidor refrescamos la pantalla o reingresamos a la URL: Obtendremos una nueva Hora, esto debido al tiempo que ha transcurrido desde que ingresamos por primera vez a la pagina hasta la segunda vez. [Capítulo 8] Página 121

122 JSP De haber ingresado lo sig. en la JSP: <html> <body> Fecha: <% out.println(tiempo.getfecha()); %> <br /> Hora: <% out.println(tiempo.gethora()); %> </body> </html> Habríamos obtenido la siguiente pantalla: [Capítulo 8] Página 122

123 JSP Existe la directiva page que tiene el atributo import Podemos evitar escribir el nombre completo de paquete con la clase usando la directiva page y utilizando el atributo import: <%@page import="com.prueba.util.*" %> <html> <body> Fecha: <% out.println(tiempo.getfecha()); %> <br /> Hora: <% out.println(tiempo.gethora()); %> </body> </html> Si quisiera mostrar la Hora desde la primera vez que uno ingresa la JSP Si queremos mostrar la Hora desde la primera vez que se ingresa a la JSP, entonces utilizamos una Declaration. [Capítulo 8] Página 123

124 JSP import="com.prueba.util.*" %> <html> <body> <%! String hora = Tiempo.getHora(); %> Hora Inicial: <% out.println(hora); %> <br /> Fecha: <% out.println(tiempo.getfecha()); %> <br /> Hora: <% out.println(tiempo.gethora()); %> </body> </html> Resultado: Al volver a refrescar la página o abrir otro navegador sin haber apagado el servidor obtenemos lo sig: [Capítulo 8] Página 124

125 JSP Evitando el uso del out.println() con Expressions: import="com.prueba.util.*" %> <html> <body> <%! String hora = Tiempo.getHora(); %> Hora Inicial: <%= hora %> <br /> Fecha: <%= Tiempo.getFecha() %> <br /> Hora: <%= Tiempo.getHora() %> </body> </html> Agregando comentarios: <%@page import="com.prueba.util.*" %> <html> <body> <!-- COMENTARIO HTML --> <%! String hora = Tiempo.getHora(); %> Hora Inicial: <%= hora %> <br /> Fecha: <%= Tiempo.getFecha() %> <br /> Hora: <%= Tiempo.getHora() %> <%-- COMENTARIO JSP --%> </body> </html> [Capítulo 8] Página 125

126 JSP Aparentemente no notamos ninguna diferencia en los comentarios pero si nos posicionamos en la JSP y si estamos utilizando Windows y oprimimos el botón derecho del mouse y seleccionamos del menú Ver código fuente... vamos a obtener: <html> <body> <!-- COMENTARIO HTML --> </body> </html> Hora Inicial: 13:22:15 hrs. <br /> Fecha: 23 de mayo de 2008 <br /> Hora: 13:22:15 hrs. Aparece en la respuesta el comentario HTML, pero el de la JSP no. [Capítulo 8] Página 126

127 JSP OBJETOS IMPLÍCITOS DE LA JSP Como pudimos observar en el servlet generado por Tomcat al inicio del método service() existe una serie de declaraciones y asignaciones que son objetos implícitos: PageContext pagecontext = null; HttpSession session = null; ServletContext application = null; ServletConfig config = null; JspWriter out = null; Object page = this; Objeto Implícito out request response session application config exception pagecontext page Tipo javax.servlet.jsp.jspwriter javax.servlet.http.httpservletrequest javax.servlet.http.httpservletresponse javax.servlet.http.httpsession javax.servlet.servletcontext javax.servlet.servletconfig java.lang.throwable javax.servlet.jsp.pagecontext java.lang.object [Capítulo 8] Página 127

128 JSP API DEL SERVLET GENERADO <<interface>> javax.servlet.jsp.jsppage void void jspinit() jspdestroy() <<interface>> javax.servlet.jsp.httpjsppage void _jspservice(httpservletrequest, HttpServletResponse) El Contenedor genera una clase desde tu JSP que implementa la interfaz HttpJspPage. Esto es lo único que nos interesa. Como lo implemente cada Contenedor como Tomcat, Weblogic o Glassfish ya es otra cosa. Por ejemplo, en Tomcat nuestro servlet generado extiende de org.apache.jasper.runtime.httpjspbase. jspinit() Este método es llamado desde el método init() del servlet. Lo puedes sobrescribir. jspdestroy() Este método es llamado desde el método destroy() del servlet. Lo puedes sobrescribir también. _jspservice() Este método es llamado desde el método service() del servlet. No lo puedes sobrescribir. De hecho no puedes hacer nada aquí. Pero como te abras dado cuenta cuando vimos el El servlet generado por Tomcat, el código que se encuentra dentro de este método es el que proviene de lo que se escribe en la JSP, tags, scriplets, expressions. [Capítulo 8] Página 128

129 JSP Por lo tanto, para sobrescribir jspinit() y jspdestroy() utilizaríamos DECLARATIONS. <%! public void jspinit() { // Aquí se ingresa código } %> CICLO DE VIDA DE LA JSP Recuerdas las fases de la JSP al inicio del capitulo? Bueno pues el ciclo de vida abarca esas fases más algo extra. 1) Tú escribes la JSP que es el archivo con extensión.jsp y lo despliegas como parte de la aplicación web. 2) El Contenedor lee el archivo web.xml (DD) para esta aplicación pero hasta ahí. No hace nada más con el archivo.jsp... hasta que recibe la primer petición. 3) Un cliente da clic en una liga o un botón el cual realiza la petición para esa JSP (archivo.jsp). [Capítulo 8] Página 129

130 JSP 4) El Contenedor traduce el archivo.jsp en un archivo.java (código fuente) para la clase del servlet. En esta etapa se atrapan los errores de sintaxis que la JSP pudiera generar. 5) El Contenedor compila el archivo.java para obtener el archivo.class. En esta etapa se atrapan los errores de sintaxis y del lenguaje que el código fuente (archivo.java) pudiera generar. 6) El Contenedor carga la nueva clase del servlet generada. 7) El Contenedor instancia el servlet y en consecuencia se ejecuta el método jspinit(). 8) El objeto es ahora un servlet listo para aceptar peticiones. 9) El Contenedor crea un nuevo hilo (thread) para manipular la petición del cliente y en consecuencia se ejecuta el método _jspservice() del servlet. [Capítulo 8] Página 130

131 JSP Todo lo que sucede después del punto 9) son simplemente peticiones al servlet por parte de los clientes. Eventualmente el servlet envía una respuesta de regreso al cliente (o redirecciona la petición a otro componente de la aplicación web). La traducción y compilación sucede una sola vez en el ciclo de vida de la JSP. Una vez que se traduce y compila, es simplemente otro servlet. Y así como cualquier otro servlet una vez que ha sido cargado e inicializado está en la posibilidad de recibir peticiones con las cuales creará o alojará hilos (threads) para ejecutar el método service(). Por lo tanto, del punto 4) hasta el punto 8) del ciclo de vida de la JSP se ejecuta únicamente para la primera petición. Aquí la pregunta sería: Existe alguna forma para que el servidor se configure para que pre-traduzca y pre-compile la JSP? Si existe pero es propia de cada vendedor. En las especificaciones se menciona algo referente a esto en el apartado JSP Precompilation Protocol. [Capítulo 8] Página 131

132 JSP Una petición a una JSP que tiene un parámetro de petición de nombre jsp_precompile es una petición de precompilacion. El parámetro jsp_precompile podría no tener valor o tener los valores true o false. En todos los casos, la petición no debería ser entregada a la JSP. La intención de la petición de precompilacion es sugerir al Contenedor precompilar la JSP. La sugerencia es llevada a cabo asignándole al parámetro el valor de true o sin asignarle valor pero hay que notar que la petición puede ser ignorada. Por ejemplo: 1.?jsp_precompile 2.?jsp_precompile=true 3.?jsp_precompile=false 4.?foobar=foobaz&jsp_precompile=true 5.?foobar=foobaz&jsp_precompile=false 1, 2, y 4 son legales; la petición no será entregada a la página. 3 y 5 son legales; la petición no será entregada a la página. 6.?jsp_precompile=foo Esto es legal y generara un error HTTP 500 (Server error). Si una JSP al final de cuentas se convierte en servlet También le podré configurar parámetros iniciales? [Capítulo 8] Página 132

133 JSP PARÁMETROS INICIALES EN UNA JSP <web-app...> </web-app> <servlet> <servlet-name>mijsp</servlet-name> <jsp-file>/mijsp.jsp</jsp-file> <init-param> <param-name> </param-name> </init-param> </servlet> <servlet-mapping> <servlet-name>mijsp</servlet-name> <url-pattern>/mijsp.jsp</url-pattern> </servlet-mapping> La única línea que es diferente respecto a un servlet es: <jsp-file>/mijsp.jsp</jsp-file> Ya que en un servlet se utiliza <servlet-class>. [Capítulo 8] Página 133

134 JSP SOBREESCRIBIR EL MÉTODO jspinit() No ya habías sobrescrito el método hace unas paginas? En el método que se sobrescribió arriba no se especificó lo que puedes usar dentro del código. <%! %> public void jspinit() { ServletConfig config = getservletconfig(); String correo = config.getinitparam(" "); ServletContext ctx = getservletcontext(); cxt.setattribute(" ", correo); } Si recordamos el ciclo de vida del servlet vamos a poder comprobar que dentro de init() y para el caso de la JSP, jspinit(), todavía no es un servlet por completo, así que solo puedes llamar a ServletConfig y a ServletContext. No podría por ejemplo obtener un parámetro de una forma o algo por el estilo. No Existe constructor init() destroy() service() [Capítulo 8] Página 134

135 JSP ATRIBUTOS Así como en el servlet se fijan atributos en cualquiera de sus tres ámbitos o alcances, en la JSP sucede lo mismo utilizando los objetos implícitos, solo que en este caso se agrega uno más (pagecontext). Generalmente no tendrás que preocuparte por el ámbito o alcance de página a menos que desarrolles etiquetas personalizadas (custom tags). Tipo de Atributo Servlet JSP Aplicación getservletcontext().setattribute(" ", correo); application.setattribute(" ", correo ); Petición request.setattribute(" ", correo); request.setattribute(" ", correo); Sesión request.getsession().setattribute((" ", correo); session().setattribute(" ", correo); Pagina No aplica. pagecontext.setattribute(" ", correo); [Capítulo 8] Página 135

136 JSP ÁMBITO O ALCANCE Agrego esta sección precisamente para tratar de aclarar el concepto (o confundirte más). En ingles se dice SCOPE y aquí lo traducimos como ámbito o alcance. Y se refiere a la cobertura que puede tener un objeto; al área que puede abarcar dicho objeto. Por ejemplo, cuando ingresamos a un parque de diversiones en muchas ocasiones existen diferentes tipos de boletos o pases para ingresar a dicho parque. Pase Básico (incluye solo juegos mecánicos). Pase Medio (incluye juegos mecánicos más espectáculos). Pase Total (incluye juegos mecánicos, espectáculos y juegos especiales). Si lo vemos como tabla y utilizamos como referencia nuestra izquierda (de izquierda a derecha sería de menos a más): Boleto o Pase Juegos mecánicos Espectáculos Juegos Especiales Básico Medio Total Observamos que el pase Medio, por ejemplo, incluye tanto Juegos mecánicos como Espectáculos pero no los Juegos Especiales. [Capítulo 8] Página 136

137 JSP Y si vemos esta tabla con una perspectiva de columnas podemos ver que si nos posicionamos en la de Espectáculos, de ahí hacia la izquierda sería mi ámbito. Abarca tanto Espectáculos como Juegos mecánicos. Por lo tanto, podríamos decir que el pase Básico es el de Juegos mecánicos, el Medio es el de Espectáculos, el Total es el Especial. Si en forma de tabla no nos fue muy claro veámoslo ahora en forma circular: TOTAL MEDIO BÁSICO Aquí el ámbito o alcance va desde el centro hasta el exterior. Hasta adentro sería el Básico, en el pase Medio observamos que su circunferencia abarca el Básico. Y finalmente el Total su circunferencia incluye tanto el Medio como el Básico. Espero no haberte mareado con esta imagen psicodélica. En realidad te pudo haber hipnotizado. A ver repite... scope es el ámbito o alcance... scope es el ámbito o alcance... scope es el ámbito o alcance. Y se refiere a la cobertura que puede tener un objeto, al área que puede abarcar dicho objeto... Y se refiere a la cobertura que puede tener un objeto, al área que puede abarcar dicho objeto... Y se refiere a la cobertura que puede tener un objeto, al área que puede abarcar dicho objeto. Bueno ya estuvo... vamos mejor a ver algo más interesante. [Capítulo 8] Página 137

138 JSP En el examen pueden sorprendernos debido a la falta de consistencia en lo que se refiere a la convención de nombres. Si te dicen context scope (ámbito de contexto) esto es incorrecto, no hay tal. Ya que cuando almacenas atributos usando ServletContext, éstos son visibles para toda la aplicación. Entonces sería application scope (ámbito o alcance de aplicación). Por lo tanto, cuando veas "Context" relaciónalo a "Application", esto es, contexto => aplicación Inconsistencia de nombres: getservletcontext().getattribute("x"); // en el servlet application.getattribute("x"); // en la JSP [Capítulo 8] Página 138

139 JSP JERARQUÍA DE CLASES DE PageContext <<abstract>> javax.servlet.jsp.jspcontext Object..getAttribute(String nombre) Object..getAttribute(String nombre, int scope) Enumeration getattributenamesinscope(int scope) Object...findAttribute(String nombre) Int..getAttributesScope(String nombre) JspWriter.getOut() void..removeattribute(string nombre) void..removeattribute(string nombre, int scope) void..setattribute(string nombre, Object valor) void..setattribute(string nombre, Object valor, int scope) // Existen más métodos <<interface>> javax.servlet.jsp.pagecontext int APPLICATION_SCOPE int SESSION_SCOPE int REQUEST_SCOPE int PAGE_SCOPE // Campos public, static, final => valores constantes // Existen otros más javax.servlet.servletrequest..getrequest() javax.servlet.servletresponset..getresponse() javax.servlet.http.httpsession getsession() javax.servlet.servletcontext getservletcontext() javax.servlet.servletconfig..getservletconfig() java.lang.exception..getexception() java.lang.object.getpage() // Obtiene todos los objetos implícitos out (getout()), viene heredado // de JspContext // Existen más métodos De acuerdo a la jerarquía descrita arriba podemos concluir que con PageContext puedes obtener atributos de cualquier ámbito o alcance. No hace falta decirlo pero por si acaso... esto incluye el del mismo PageContext. Hay dos métodos sobrecargados de getattribute(), uno es más intuitivo que el otro. El que tiene 2 argumentos le especificas el ámbito o alcance del atributo que quieres obtener, esto es, cualquiera de los cuatro posibles. Pero en el que recibe un solo argumento es solo para atributos ligados al objeto pagecontext. [Capítulo 8] Página 139

140 EL Y JSTL Capítulo 9 EL y jstl [Capítulo 9] Página 140

141 EL Y JSTL INTRODUCCIÓN Bueno finalmente estamos llegando a los capítulos que muchas veces dejamos de leer porque... o el libro estaba aburrido (seguramente este no es caso) o porque ya no nos dio tiempo. Pero resulta que son los capítulos efectivos. Los que vale la pena leer. Y no lo digo para forzarte a leer estos últimos capítulos sino que es la verdad... de veras. Bueno comencemos... Al final de cuentas los scriptless son dañinos. Será cierto esto? Pues no el problema era que las páginas eran estáticas (HTML) y surgió la necesidad de algo dinámico y se logró ingresar código java dentro de la JSP? Por qué sería malo usar código java dentro de una JSP? Imagínate a un Desarrollador Web, él solo conoce HTML, quizás programas de diseño artístico, etc. No es programador. Y al decirle que desarrolle JSPs con scriptless lo estamos obligando a aprender java, lo obligamos a programar de alguna manera. [Capítulo 9] Página 141

142 EL Y JSTL Entonces por qué tener que aprender todo eso de scriptless? En primer lugar porque viene en el examen. Pero esa no es la razón principal. Precisamente quienes lo incluyeron en el examen tomaron en cuenta que afuera en el campo, en muchas de las aplicaciones hechas con anterioridad hay un montón de JSPs que utilizan scriptless y por eso mismo es necesario conocerlo. Imagínate que tuvieras que hacer una migración, una modificación o algo por el estilo. Pero entonces cuál sería la alternativa? La alternativa sería usar "EL" (Expression Language). "EL" son las siglas de Expression Language. "EL" fue agregado en la especificación 2.0 de JSP. "EL" te permite acceder a objetos java sin necesidad de conocer java. "EL" te ofrece una manera más simple de invocar este código. En el capítulo anterior pudimos observar que las JSPs pueden omitir el uso de scripts usando las acciones estándar. Y como se había comentado esto es una forma conveniente para evitar el uso de código java dentro de la JSP. Pero... Las acciones estándar hacen llamados a métodos get() y set() del Bean... Cómo se utiliza "EL"? [Capítulo 9] Página 142

143 EL Y JSTL Operadores "[]" y "." Cuando se utiliza "EL", lo podemos hacer por medio de 2 operadores. No tienen un nombre específico. Son: 1. [] 2.. El primero utiliza lo que llamamos corchetes. El segundo simplemente es un punto. Sintaxis: Operador Punto (.) ${expresión} ${bean.propiedad} ${map.key} Siempre comienza con el signo de pesos ($) y la expresión se encuentra dentro de las llaves. La primera variable antes del punto es un Bean o java.util.map. Esto es, puede ser un objeto implícito de "EL" o un atributo (en cualquiera de sus ámbitos o alcances: page, request, session, application). Así es... "EL" tiene objetos implícitos... como las JSP. La segunda variable después del punto debe ser la propiedad de un Bean o la llave (key) de un java.util.map. NOTA: Cuando digo Bean me refiero a un Bean de Java, no a un Enterprise Java Bean (EJB). Este Bean tiene variables de instancia con métodos getters y setters. [Capítulo 9] Página 143

144 EL Y JSTL Ejemplo: ${empleado.nombre} java.util.map o Bean "nombre", "X" getnombre() setnombre() Reglas para nombre : Debe iniciar con una letra, guión bajo (_) o $ Después del primer carácter, se pueden incluir números No puede ser una palabra reservada de java Operador [] El operador punto solo funciona cuando lo que esta después del punto resulta ser la llave de un Map o la propiedad de un Bean. Cuando se utiliza el operador [] es mucho más flexible ya que a parte del java.util.map y del Bean puede ser un Arreglo o una lista (java.util.list). Sintaxis: Operador [] ${bean["propiedad"]} ${map["key"]} ${map[objeto]} ${arreglo["indice"]} ${lista["indice"]} Si dentro de los corchetes ([]) no existen comillas entonces el Contenedor evalúa el contenido. Ejemplo: map[x] => Busca un atributo llamado "x". Usa el valor de ese atributo como la llave dentro de un Map o regresa null. [Capítulo 9] Página 144

145 EL Y JSTL OPERADORES ARITMÉTICOS DE "EL" NOMBRE OPERADOR ALTERNATIVO Suma + Resta - Multiplicación * División / div Residuo (modulo) % mod OPERADORES RELACIONALES DE "EL" NOMBRE OPERADOR ALTERNATIVO Igual == eq Diferente!= ne Menor que < lt Mayor que > gt Menor o igual que <= le Mayor o igual que >= ge OPERADORES LÓGICOS DE "EL" OPERADOR ALTERNATIVO && and or! not [Capítulo 9] Página 145

146 EL Y JSTL OBJETOS IMPLÍCITOS DE "EL" pagescope requestscope sessionscope applicationscope header headervalues Todos estos son Map param paramvalues initparam cookie pagecontext Este es el único que no es un Map. Este es un JavaBean Los objetos implícitos de "EL"... NO SON LOS MISMOS que los objetos implícitos de la JSP a excepción de pagecontext. [Capítulo 9] Página 146

147 EL Y JSTL JSTL Son las siglas de Java Server Pages Standard Tag Library y la especificación que a continuación se abarcará es la 1.1. Fué desarrollada por el grupo de expertos JSR-52 bajo el Java Community Process ( La meta de JSTL es ayudar a simplificar el desarrollo de JSPs. Pero como logar esto? Bueno pues como se había comentado anteriormente una persona que desarrolla paginas web, no necesariamente tiene que saber un lenguaje de programación como Java. Esto para poder manipular los datos de forma dinámica dentro de la JSP. Lo que hicieron estas personas fue crear una serie de librerías de tags (etiquetas). Estos tags encapsulan la funcionalidad para ser usada dentro de las JSPs. Una de las partes claves de JSTL es el soporte que tiene para "EL". INSTALACIÓN DE JSTL 1.1 JSTL NO es parte de la especificación de JSP 2.0. El tener acceso a las APIs de Servlets y JSPs no significa poder acceder a JSTL. Antes de poder utilizar JSTL necesitas poner 2 archivos dentro del directorio WEB-INF/lib de tu aplicación. 1. jstl.jar 2. standard.jar O sea que cada aplicación web que desarrolles necesitara este par de archivos. [Capítulo 9] Página 147

148 EL Y JSTL Dónde consigo estos 2 archivos? En Tomcat 5 en las aplicaciones de ejemplo dentro de: 1. webapps/jsp-examples/web-inf/lib/jstl.jar 2. webapps/jsp-examples/web-inf/lib/standard.jar Veamos los tags que vienen en el examen: <c:out> Evalúa una expresión y entrega el resultado de la evaluación al objeto actual JspWriter. Sintaxis sin cuerpo: <c:out value="valor" [escapexml="true false"] [default="valorpordefault"] /> Sintaxis con cuerpo: <c:out value="valor" [escapexml="true false"]> </c:out> valorpordefault [Capítulo 9] Página 148

149 EL Y JSTL Atributos Nombre Dinámico Tipo Descripción value verdadero Object Expresión a ser evaluada. escapexml verdadero boolean Determina si los caracteres <, >, &, ', " en el string resultante deberán ser convertidas a su correspondiente código. El valor por default es true. default verdadero Object Valor por default si el valor resultante es null. Por default <c:out> convierte los caracteres <, >, ', ", & a su correspondiente código. Esto es, el valor de escapexml por default es true. Por ejemplo, < es convertida a < Si estos caracteres no fueran convertidos la página no sería traducida apropiadamente por el navegador. Y también podría dejar huecos para posibles ataques. Por ejemplo, alguien podría enviar algo hecho en JavaScript para hackear el sistema (modificar o alterar el funcionamiento del sistema). A esto le llaman cross-site hacking o cross-site scripting. El utilizar <c:out> previene que el código JavaScript mailicioso se ejecute, esto es, que sea interpretado por el navegador. La conversión puede omitirse utilizando el atributo escapexml con valor igual a false. <c:out> también soporta valores por default utilizando el atributo default. [Capítulo 9] Página 149

150 EL Y JSTL Si escapexml="true entonces se aplica la sig. conversión: Manejo de Nulos y Errores Carácter Código < < > > & & ' &#39; " " Si value es null se toma el valor default. Si no se especifica default envía un string vacío. Ejemplos: <c:out value="${cliente.direccion.ciudad}" default="desconocido" /> <c:out value="${user.nombre}" escapexml="true" /> Resumen: La expresión a ser evaluada es especificada por el atributo value. El resultado de la evaluación es convertido a String y subsecuentemente emitido hacia el objeto actual JspWriter. [Capítulo 9] Página 150

151 EL Y JSTL Ejemplo: Bean: package com.scwcd.beans; public class Empleado { private String nombre; public String getnombre() { return nombre; } } public void setnombre(string nombre) { this.nombre = nombre; } En el Servlet: package com.scwcd.servlets; import java.io.ioexception; import javax.servlet.requestdispatcher; import javax.servlet.servletexception; import javax.servlet.http.httpservlet; import javax.servlet.http.httpservletrequest; import javax.servlet.http.httpservletresponse; import com.scwcd.beans.empleado; public class EmpleadoServlet extends HttpServlet { public void dopost(httpservletrequest request, HttpServletResponse response) throws IOException, ServletException { Empleado emp = new Empleado(); emp.setnombre("juan"); request.setattribute("empleado", emp); } RequestDispatcher view = request.getrequestdispatcher("jstl_out-1.jsp"); view.forward(request, response); } [Capítulo 9] Página 151

152 EL Y JSTL En el web.xml: <servlet> <servlet-name>empleadoservlet</servlet-name> <servlet-class>com.scwcd.servlets.empleadoservlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>empleadoservlet</servlet-name> <url-pattern>/employee</url-pattern> </servlet-mapping> prueba.html: <html> <body> <form method="post" action="employee"> <input type="submit" /> </form> </body> </html> [Capítulo 9] Página 152

153 EL Y JSTL jstl-out-1.jsp: <%@ taglib prefix="c" uri=" %> <html> <head> <title>jstl</title> </head> <body> <c:out value="empleado: ${empleado.nombre}" /> </body> </html> [Capítulo 9] Página 153

154 EL Y JSTL <c:set> Fija o establece el valor de una variable con alcance "x" o una propiedad de un objeto. <c:set> a diferencia de <jsp:setproperty> que solo puede fijar o establecer la propiedad de un bean, también puede establecer el valor en un Map o crear un nueva entrada en un Map o crear un nuevo atributo. Sintaxis 1: Fija el valor de una variable con alcance x usando un valor de atributo. <c:set value="valor" var="nombrevariable" [scope="{page request session application}"] /> Sintaxis 2: Fija el valor de una variable con alcance x usando contenido en el cuerpo. <c:set var="nombrevariable" [scope="{page request session application}"]> </c:set> CUERPO Sintaxis 3: Fija una propiedad de un objeto usando el valor de un atributo. <c:set value="valor" target="objetivo" property="nombrepropiedad " /> Sintaxis 4: Fija una propiedad de un objeto usando contenido en el cuerpo. <c:set target="objetivo" property="nombrepropiedad "> </c:set> CUERPO [Capítulo 9] Página 154

155 EL Y JSTL <c:set> se usa para fijar el valor de un atributo con ámbito o alcance de JSP, esto es, solo dentro de la misma JSP. Atributos Nombre Dinámico Tipo Descripción value verdadero Object Expresión a ser evaluada. var falso String Nombre de la variable exportada que mantiene el valor especificado en la acción. scope falso String Alcance de la variable. target verdadero Object Objeto cuya propiedad será fijada. property verdadero String Nombre de la propiedad a ser fijada en el objeto. Manejo de Nulos y Errores La sintaxis 3 y 4 lanzaran una excepción si: target es null target no es un java.util.map o un JavaBean que soporte fijar la propiedad property Si value es null: Para la Sintaxis 1: la variable definida por var y scope es eliminada. Para la Sintaxis 3: Si target es un Map, quita el registro con la llave identificada por la propiedad. Si target es un JavaBean, fija la propiedad a null. [Capítulo 9] Página 155

156 EL Y JSTL Resumen: <c:set> viene en 2 versiones, var y target: var es para fijar o establecer variables de atributos. target es para fijar o establecer propiedades de un bean o valores de un Map. Las sintaxis 1 y 2 fijan o establecen el valor de una variable con alcance "x" identificada por var y scope. Para las sintaxis 3 y 4: Si la expresión target es un objeto java.util.map, fija o establece el valor del elemento asociado con la llave identificada por property. Si el elemento no existe, lo agrega al objeto Map. En caso contrario, fija o establece el valor de la propiedad property del objeto JavaBean target. Si el tipo de valor a fijar o establecer no encaja con el tipo de la propiedad del bean, la conversión se lleva a cabo de acuerdo con las reglas de conversión definidas en "EL". Con la excepción de un valor null, fijar o establecer la propiedad de un bean con <c:set> es exactamente igual a fijar el valor de un atributo de una acción usando "EL". Una falla en las reglas de conversión para determinar un tipo apropiado de coerción nos lleva a una JspException en tiempo de ejecución. Si el valor de value es null entonces la variable será BORRADA. Si por ejemplo tenemos: <c:set var="emp" scope="request" value="${empleado.nombre}" /> Y resulta que no existe el empleado o la propiedad nombre es null, entonces la variable emp será borrada. [Capítulo 9] Página 156

157 EL Y JSTL Y cuales son esas reglas de conversión definidas en "EL" a las que se refiere? REGLAS DE CONVERSIÓN DEFINIDAS EN "EL" Cada expresión es evaluada en el contexto de un tipo de dato esperado. El resultado de la evaluación de la expresión podría no encajar con el tipo de dato esperado, así que las siguientes reglas serían aplicadas: COERCIÓN X A UN STRING Si X es un String: devuelve X En caso contrario, si X es null: devuelve "" En caso contrario, si X.toString() lanza una excepción => error En caso contrario: devuelve X.toString() En caso contrario, si X es un tipo primitivo, devuelve un String como en la siguiente expresión java: "" + X COERCIÓN X A UN TIPO PRIMITIVO N Si X es null o "": devuelve 0 Si X es Character: convierte a short, aplica las sig. reglas Si X es un Bolean => error Si X es Number de tipo N: devuelve X Si X es Number con menos precisión que N => coerción leve Si X es Number con mayor precisión que N => coerción leve [Capítulo 9] Página 157

158 EL Y JSTL Si X es un String y un nuevo N.valueOf(X) lanza una excepción: => error Si X es un String y N.valueOf(X) no lanza una excepción: => lo devuelve En caso contrario => error COERCIÓN X A UN Character Si X es null o "": devuelve (char)0 Si X es un Character: devuelve X Si X es un Bolean => error Si X es un Number con menor precisión que un short: coerción leve => devuelve (char)x Si X es un Number con mayor precisión que un short: coerción leve => devuelve (char)x Si X es un String: devuelve X.charAt(0) En caso contrario => error COERCIÓN X A UN Boolean Si X es null o "": devuelve false En caso contrario si X es Boolean: devuelve X En caso contrario si X es un String y Boolean.valueOf(X) lanza una excepción => error En caso contrario si X es un String devuelve Boolean.valueOf(X) En caso contrario => error COERCIÓN X A CUALQUIER OTRO TIPO T S X es null: devuelve null Si X se puede asignar a T: coerción tranquilamente Si X es un tipo de dato primitivo: devuelve un objeto empaquetado con valor equivalente, como se muestra a continuación: o Si X es un int: devuelve new Integer(X) o Si X es un flota: devuelve new Flota(X) Si X es un String y T no tiene un PropertyEditor: o Si X es "": devuelve null [Capítulo 9] Página 158

159 EL Y JSTL o En caso contrario => error Si X es un String y el PropertyEditor de T lanza una excepción: o Si X es "": devuelve null o En caso contrario => error En caso contrario, aplica el PropertyEditor de T En caso contrario => error Ejemplo 1: En el Servlet: package com.scwcd.servlets; import java.io.ioexception; import javax.servlet.requestdispatcher; import javax.servlet.servletexception; import javax.servlet.http.httpservlet; import javax.servlet.http.httpservletrequest; import javax.servlet.http.httpservletresponse; public class SetServlet extends HttpServlet { public void dopost(httpservletrequest request, HttpServletResponse response) throws IOException, ServletException { String pagina = "pagina 1"; request.setattribute("pagina", pagina); } } RequestDispatcher view = request.getrequestdispatcher("jstl_set-1.jsp"); view.forward(request, response); En el web.xml: <servlet> <servlet-name>setservlet</servlet-name> <servlet-class>com.scwcd.servlets.setservlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>setservlet</servlet-name> <url-pattern>/set</url-pattern> </servlet-mapping> [Capítulo 9] Página 159

160 EL Y JSTL prueba.html: <html> <body> <form method="post" action="set"> <input type="submit" /> </form> </body> </html> jstl-set-1.jsp: <%@ taglib prefix="c" uri=" %> <html> <head> <title>jstl</title> </head> <body> <c:set var="pag" scope="request" value="${pagina}" /> <c:out value="${pag}" /> </body> </html> [Capítulo 9] Página 160

161 EL Y JSTL Ejemplo 2: En el Servlet: package com.scwcd.servlets; import java.io.ioexception; import javax.servlet.requestdispatcher; import javax.servlet.servletexception; import javax.servlet.http.httpservlet; import javax.servlet.http.httpservletrequest; import javax.servlet.http.httpservletresponse; public class Set2Servlet extends HttpServlet { public void dopost(httpservletrequest request, HttpServletResponse response) throws IOException, ServletException { } } RequestDispatcher view = request.getrequestdispatcher("jstl_set-2.jsp"); view.forward(request, response); En el web.xml: <servlet> <servlet-name>set2servlet</servlet-name> <servlet-class>com.scwcd.servlets.set2servlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>set2servlet</servlet-name> <url-pattern>/set2</url-pattern> </servlet-mapping> [Capítulo 9] Página 161

162 EL Y JSTL prueba.html: <html> <body> <form method="post" action="set2"> <input type="submit" /> </form> </body> </html> jstl-set-2.jsp: <%@ taglib prefix="c" uri=" %> <html> <head> <title>jstl</title> </head> <body> <c:set var="num" scope="request"> Uno, Dos, Tres </c:set> <c:out value="${num}" /> </body> </html> [Capítulo 9] Página 162

163 EL Y JSTL <c:remove> Quita una variable de alcance "x". Sintaxis: <c:remove var= nombrevariable [scope= {page request session application} ]/> Atributos Nombre Dinámico Tipo Descripción var falso String Nombre de la variable de alcance "x" a ser removida. scope falso String Alcance para var. Si el atributo scope no es especificado, la variable es removida de acuerdo a la semántica de: PageContext.removeAttribute(nombreVariable) Si el atributo scope es especificado, la variable es removida de acuerdo a la semántica de: PageContext.removeAttribute(nombreVariable, scope) [Capítulo 9] Página 163

164 EL Y JSTL <c:catch> Atrapa un java.lang.throwable lanzado por cualquiera de sus acciones anidadas. Sintaxis: <c:catch [var= nombrevariable ]> </c:catch> acciones anidadas Atributos Nombre Dinámico Tipo Descripción var falso String Nombre de la variable de alcance "x" para la excepción lanzada desde una acción anidada. El tipo de la variable es del tipo de la excepción lanzada. La acción <c:catch> permite a los diseñadores de paginas manejar errores de cualquier acción de una manera uniforme y permite el manejo de errores para múltiples acciones. <c:catch> provee a los diseñadores de paginas un manejo de errores granular: Las acciones que son de importancia central para una pagina no deben ser encapsuladas en un <c:catch> para que sus excepciones sean propagadas a una pagina de error, mientras que las acciones con una importancia secundaria deben ser atrapadas en un <c:catch>, para que nunca invoquen a la pagina de error. La excepción lanzada es almacenada en la variable identificada por var, la cual tiene siempre un ámbito o alcance de page. Si no ocurre ninguna excepción, la variable identificada por var es removida si existiera. Si var no estuviera, la excepción simplemente es atrapada y no guardada. [Capítulo 9] Página 164

165 EL Y JSTL <c:if> Evalúa el contenido de su cuerpo si la expresión especificada con el atributo test es verdadera. Sintaxis sin contenido en el cuerpo: <c:if test= condición var="nombrevariable " [scope="{page request session application} "] /> Sintaxis con contenido en el cuerpo: <c:if test= condición [var="nombrevariable " ] [scope="{page request session application} "]> contenido </c:if> Si la condición es verdadera, el contenedor de la JSP procesa el contenido del cuerpo y lo escribe al JspWriter. Atributos Nombre Dinámico Tipo Descripción test verdadero boolean La condición test que determina si sí o no el contenido del cuerpo debe ser procesado. var falso String Nombre de la variable de alcance "x" exportada para el valor resultante de la condición test. El tipo de la variable es Boolean. scope falso String Ámbito o alcance para var. Si scope es especificado entonces var debe ser especificado. [Capítulo 9] Página 165

166 EL Y JSTL <c:choose> Procesa el cuerpo de la primera acción <c:when> cuya condición test evalúa a verdadero. Si ninguna de las condiciones test de las acciones <c:when> anidadas evalúa a verdadero, entonces el cuerpo de la acción <c:otherwise> es procesado si se encuentra presente. Sintaxis: <c:choose> contenido del cuerpo (<c:when> y <c:otherwise>) </c:choose> Restricciones El cuerpo de la acción <c:choose> solo puede contener: o Espacios en blanco Pueden aparecer en cualquier lado alrededor de <c:when> y <c:otherwise> o 1 o más acciones <c:when> Todas deben aparecer antes de <c:otherwise> o 0 ó 1 <c:otherwise> Debe ser la última acción anidada dentro de <c:choose> [Capítulo 9] Página 166

167 EL Y JSTL <c:when> Representa una alternativa dentro de la acción <c:choose>. Si es la primera acción <c:when> que evalúa a verdadero entonces el contenedor de JSP procesa el contenido del cuerpo y lo escribe al actual JSpWriter. Sintaxis: <c:when test="condición"> </c:when> contenido del cuerpo Atributos Nombre Dinámico Tipo Descripción test vedadero boolean La condición test que determina si sí o no el contenido del cuerpo debe ser procesado. Restricciones Debe tener <c:choose> como padre inmediato. Debe aparecer antes de una acción <c:otherwise> que tiene el mismo padre. [Capítulo 9] Página 167

168 EL Y JSTL <c:otherwise> Representa la última alternativa dentro de la acción <c:choose>. Si ninguna de las acciones anidadas <c:when> dentro de <c:choose> es verdadera, el contenedor de JSP procesa el contenido del cuerpo y lo escribe al actual JspWriter. Sintaxis: <c:otherwise> bloque condicional </c:otherwise> Restricciones Debe tener <c:choose> como padre inmediato. Debe ser la ultima acción anidada dentro de <c:choose> [Capítulo 9] Página 168

169 EL Y JSTL <c:foreach> Iterar sobre una colección de objetos es una práctica muy común dentro de una JSP. Un simple scriplet nos podría resolver el problema. Pero nuevamente regresamos a nuestras viejas y endemoniadas prácticas donde obligamos a nuestros Diseñadores Web a tener que saber algunos aspectos del lenguaje de Java, en este caso, iterar sobre colecciones. Las acciones de iteración que ofrece JSTL nos simplifican lo anterior. <c:foreach> repite el contenido de su cuerpo en base a una colección de objetos o lo repite un número de veces fijo. Siempre y cuando haya elementos sobre los cuales iterar, el contenido del cuerpo es procesado por el contenedor JSP y escrito al actual JspWriter. Sintaxis 1: Itera sobre una colección de objetos <c:foreach [var="nombrevariable "] items="collection " [varstatus="status "] [begin="inicio "] [end="fin "] [step="paso "]> contenido del cuerpo </c:foreach> Sintaxis 2: Itera sobre un número de veces fijo <c:foreach [var="nombrevariable "] [varstatus="status "] begin="inicio " end="fin " [step="paso "]> contenido del cuerpo </c:foreach> [Capítulo 9] Página 169

170 EL Y JSTL Atributos Nombre Dinámico Tipo Descripción var falso String Nombre de la variable de alcance "x" exportada para el elemento actual de la iteración. Esta variable tiene visibilidad anidada. Su tipo depende del objeto de la colección. items verdadero Cualquiera de los tipos soportado s Colección de elementos sobre los que se va a iterar. varstatus falso String Nombre de la variable de alcance "x" exportada para el estatus de la iteración. El objeto exportado es del tipo javax.servlet.jsp.jstl.core.looptags tatus. Tiene visibilidad anidada. begin verdadero int Si los elementos son especificados: La iteración comienza en el elemento localizado en el índice especificado. El primer elemento de la colección tiene índice 0. Si los elementos no son especificados: La [Capítulo 9] Página 170

171 EL Y JSTL iteración comienza con el índice puesto en el valor especificado. end verdadero int Si los elementos son especificados: La iteración termina en el elemento localizado en el índice especificado (inclusivo). Si los elementos no son especificados: La iteración termina cuando el índice alcanza el valor especificado. step verdadero int La iteración será procesada por pasos comenzado con el primero. Restricciones Si es especificado, begin debe ser >= 0. Si es especificado, end debe ser >= begin. Si es especificado, step debe ser >= 1. Manejo de Nulos y Errores Si items es null, es tratado como una colección vacía, por ejemplo, no se realiza ninguna iteración. Si begin es mayor o igual que numero de items, no se realiza ninguna iteración. Los siguientes tipos de datos listados a continuación son admitidos por items. [Capítulo 9] Página 171

172 EL Y JSTL Con la Sintaxis 1, cada objeto expuesto por el atributo var es del tipo del objeto de la colección, excepto para los arreglos de tipos primitivos y mapas. Con la Sintaxis 2, el objeto exportado es de tipo Integer. Arreglos (Arrays) Estos incluyen arreglos de objetos así como arreglos de tipo primitivo. Para los arreglos de tipo primitivo el elemento actual para la iteración es empaquetada automáticamente con su correspondiente clase Wrapper (por ejemplo, Integer para int, Flota para flota, etc). Implementación de java.util.collection. Un objeto Iterator se obtiene de una colección por medio del método iterator() y los elementos de la colección son procesados en el orden en que fueron regresados por el objeto Iterator. Implementación de java.util.iterator. Los elementos de la colección son procesados en el orden en que fueron regresados por el objeto Iterator. Implementación de java.util.enumeration. Los elementos de la colección son procesados en el orden en que fueron regresados por el objeto Enumeration. [Capítulo 9] Página 172

173 EL Y JSTL Implementación de java.util.map El objeto expuesto por medio del atributo var es del tipo Map.Entry. Se obtiene un Set del Map por medio del método entryset(), del cual un objeto Iterator puede ser obtenido por medio del método iterator(). Los elementos de la colección son procesados en el orden en que fueron regresados por el objeto Iterator. String La cadena (string) representa una lista de valores separados por coma, donde el carácter coma es el símbolo delimitador. Los símbolos son procesados en su orden secuencial en la cadena (string). [Capítulo 9] Página 173

174 EL Y JSTL <c:import> Importa el contenido de un recurso basado en URL. Sintaxis 1: Contenido del recurso integrado o exportado como objeto String <c:import url="url " [context="contexto "] [var="nombrevariable "] [scope="{page request session application} "] [charencoding="codificación "]> contenido del cuerpo opcional para <c:param> </c:import> Sintaxis 2: Contenido del recurso exportado como objeto Reader <c:import url="url " [context="contexto "] varreader="nombrereader " [charencoding="codificación "]> contenido del cuerpo donde varreader es consumido por otra acción </c:import> El contenido del cuerpo es procesado por el contenedor JSP y el resultado es escrito al actual JspWriter. [Capítulo 9] Página 174

175 EL Y JSTL Atributos Nombre Dinámico Tipo Descripción url verdadero String La URL del recurso a importar. context verdadero String Nombre del contexto cuando se accede a un recurso relativo de una URL que pertenece a un contexto ajeno. var falso String Nombre de la variable de alcance "x" exportada para el contenido del recurso. El tipo de la variable es String. scope falso String Ámbito o alcance para var. charencoding verdadero String Codificación de caracteres del contenido al ingreso del recurso. varreader falso String Nombre de la variable de alcance "x" exportada para el contenido del recurso. El tipo de la variable es Reader. [Capítulo 9] Página 175

176 EL Y JSTL Manejo de Nulos y Errores Si url es null, vació o invalido se lanza una JspException. Si charencoding es null o vació se considera perdido. Para recursos internos: (a) Si un RequestDispatcher no puede ser encontrado por el recurso lanza una JspException con la ruta del recurso incluida en el mensaje. (b) En caso contrario, si el método RequestDispatcher.include() lanza un IOException o un RuntimeException, lanza un JspException con la excepción atrapada como la causa raíz. (c) En caso contrario, si el método RequestDispatcher.include() lanza un ServletException busca por una causa raíz. Si hay una causa raíz, lanza una JspException con el mensaje de la causa raíz incluida en el mensaje y la causa raíz original como JspException causa raíz. En caso contrario, hace lo mismo que en el inciso (b). (d) En caso contrario, si el recurso invocado a través del método RequestDispatcher.include() pone un código de estatus de la respuesta diferente de 2xx (por ejemplo, , el rango de códigos exitosos en los códigos de respuesta de HTTP), lanza una JspException con la ruta y código de estatus en el mensaje. Para recursos externos Si la clase URLConnection lanza un IOException o un RuntimeException, lanza un JspException con el mensaje de la excepción original incluida en el mensaje y la excepción original como la causa raíz. Para un HttpURLConnection, si el código de estatus de la respuesta es diferente de 2xx (por ejemplo, , el rango de códigos exitosos en los códigos de respuesta de HTTP), lanza un JspException con la ruta y el código de estatus en el mensaje. [Capítulo 9] Página 176

177 EL Y JSTL Usando la sintaxis 1, el contenido del recurso es por default escrito al actual JspWriter. Si var es especificada, el contenido del recurso es en cambio expuesto como objeto String. Usando la sintaxis 2, el contenido del recurso es exportado como un objeto Reader. El uso del atributo varreader viene con ciertas restricciones. URL Relativa (mismo contexto) URLs Relativas y Absolutas Esto es procesado exactamente de la misma forma como lo hace la acción include de la JSP (<jsp:include>). El recurso pertenece a la misma aplicación web al igual que la pagina que se esta incluyendo y es especificada como URL Relativa. Como se establece en la especificación de JSP, un URL Relativo puede ser una ruta de contexto-relativo o una ruta de paginarelativa. Una ruta de contexto-relativo es una ruta que comienza con el slash hacia delante, "/ ". Se interpreta como relativo a la aplicación a la cual pertenece la pagina JSP. Una ruta de pagina-relativa es una ruta que no comienza con el slash hacia delante, "/ ". Se interpreta como relativo a la actual pagina JSP, como se define en las reglas de inclusión de la acción <jsp:include> de la especificación de JSP. Las semánticas de importar un recurso especificado con una URL Relativa en el mismo contexto son las mismas que un include realizado por un RequestDispatcher como se define en la especificación del Servlet. Esto significa que todo el ambiente de importación de la pagina esta disponible para el recurso (incluyendo atributos de petición y sesiona si como parámetros de petición de la pagina a importar). [Capítulo 9] Página 177

178 EL Y JSTL URL Relativa (contexto foráneo) El recurso pertenece a un contexto foráneo (aplicación web) hospedada bajo el mismo contenedor que la pagina a importar. El nombre del contexto para el recurso es especificado por medio del atributo context. La URL Relativa debe ser de contexto-relativo (por ejemplo, debe iniciar con "/ ") ya que la pagina a incluir no pertenece al mismo contexto. De forma similar, el nombre del contexto debe también iniciar con "/ ". Las semánticas de importar un recurso especificado con una URL Relativa en un contexto foráneo son las mismas que un include realizado por un RequestDispatcher en un contexto foráneo como se define en la especificación del Servlet. Esto significa que solo el ambiente de petición de la pagina que se esta importando esta disponible para el recurso objetivo. Es importante notar que los recursos a importar en contextos foráneos podrían no trabajar en todos los contenedores. Podría existir un ambiente de seguridad que no permitiera el acceso a contextos foráneos. Un recurso en un contexto foráneo también puede ser accesado usando una URL absoluta. Sin embargo, es más eficiente usar una URL Relativa porque el recurso es entonces accedido usando RequestDispatcher definido por la API del Servlet. [Capítulo 9] Página 178

179 EL Y JSTL URL Absoluta Las URLs absolutas son recuperadas como se define en las clases java.net.url y java.net.urlconnection. De esta manera la acción <c:import> soporta al menos los protocolos ofrecidos en la plataforma J2SE 1.2 para URLs absolutas. Puede haber más protocolos disponibles para una aplicación web, pero esto dependerá de las librerías de clases que se encuentren disponibles para la aplicación web. Cuando se usa una URL absoluta para importar un recurso, nada del actual ambiente en ejecución (por ejemplo, los atributos de petición y de sesión) esta disponible para el recurso objetivo, aun si la URL absoluta apunta al mismo host y ruta del contexto. De esta manera, los parámetros de petición de la pagina que se esta importando no son propagados a la URL absoluta. Cuando se importa un recurso externo usando el protocolo http, <c:import> se comporta de acuerdo a las semánticas de la petición GET enviada por medio de la clase java.net.httpurlconnection con setfollowredirects puesto en true. Ejemplos de URL absolutos: Ejemplos de URL relativos: //en.wikipedia.org/wiki/uniform_resource_locator /wiki/url URL#Referencias_URI [Capítulo 9] Página 179

180 EL Y JSTL <c:url> Construye una URL con las apropiadas reglas de reescritura aplicadas. Sintaxis 1: Sin contenido en el cuerpo <c:url value="valor " [context="contexto "] [var="nombrevariable "] [scope="{page request session application} "] /> Sintaxis 2: Con contenido en el cuerpo para especificar los parámetros del query string <c:url value="valor " [context="contexto "] [var="nombrevariable "] [scope="{page request session application} "] > <c:param> subtags </c:url> Atributos Nombre Dinámico Tipo Descripción value verdadero String URL a ser procesada. context verdadero String Nombre del contexto cuando se especifica un recurso en una URL Relativa que pertenece a un contexto foraneo. var falso String Nombre de la variable de alcance "x" exportada para la url procesada. El tipo de la variable es String. scope falso String Ámbito o alcance para var. [Capítulo 9] Página 180

181 EL Y JSTL <c:url> procesa una URL y la reescribe si es necesario. Solo los URLs relativos son reescritos. Los URLs absolutos no son reescritos para prevenir situaciones donde un URL externo pudiera ser reescrito y exponer su ID de sesión. Una consecuencia es que si un diseñador de paginas web quiere llevar el seguimiento de la sesión, solo las URLs relativas deben ser usadas con <c:url> para ligar a recursos locales. La reescritura debe ser realizada llamando al método encodeurl() de la API del Servlet. Si la URL contiene caracteres que deben ser codificados (por ejemplo, espacios) es la responsabilidad del usuario codificarlos. La URL debe ser ya sea absoluta comenzando con un esquema (por ejemplo, " o relativa como se define en la especificación de JSP 1.2. Es posible especificar una URL en un contexto foráneo por medio del atributo context. La URL debe comenzar con "/ " (ya que es una URL de contexto-relativo). [Capítulo 9] Página 181

182 EL Y JSTL <c:param> Agrega parámetros de petición a una URL. Es una acción anidada de <c:import>, <c:url> y <c:redirect>. Sintaxis 1: Valor del parámetro especificado en el atributo "value": <c:param name="nombre " value="valor " /> Sintaxis 2: Valor del parámetro especificado en el contenido del cuerpo: <c:param name="nombre "> valor del parámetro </c:param> Atributos Nombre Dinámico Tipo Descripción name verdadero String Nombre del parámetro. value falso String Valor del parámetro. Manejo de Nulos y Errores Si name es null o vació, no se realiza ninguna acción. No es un error. Si value es null, es procesado como un valor vació. [Capítulo 9] Página 182

183 EL Y JSTL Uno podría argumentar que lo siguiente es redundante: <c:import url= /exec/doit > <c:param name= action value= register /> </c:import> ya que es lo mismo que esto: <c:import url= /exec/doit?action=register /> Es en efecto... redundante, pero es consistente con <jsp:include>, el cual soporta subelementos <jsp:param> anidados. Además ha sido diseñado de tal forma que los atributos name y value son automáticamente codificados. [Capítulo 9] Página 183

184 EL Y JSTL RESUMEN JSTL (JSP STANDARD TAG LIBRARY) Etiqueta Descripción Atributos Establece el valor de una variable. var : nombre de la variable. value : valor de la variable, puede ser una expresión. scope : alcance de <c:set> la variable (es opcional, el valor por default es page). El alcance de una variable puede ser page, request, session, application. Ejemplo: <c:set var="x" value="${5+8}" /> <c:remove> Elimina una variable. var : nombre de la variable. scope : alcance de la variable (es opcional, el valor por default es page). El alcance de una variable puede ser page, request, session, application. Ejemplo: <c:remove var="x"/> <c:if> Si la condición test es verdadera entonces su cuerpo se ejecuta. test : condición Ejemplo: <c:if test="${x=8}"> x es igual a 8 [Capítulo 9] Página 184

185 EL Y JSTL </c:if> Etiqueta Descripción Atributos Permite manejar test : condición varias condiciones que se utiliza en como si fueran if la etiqueta when. <c:choose> pero también <c:when> permite una <c:otherwise> especie de else utilizando el <c:otherwise> Ejemplo: <c:choose> <c:when test="${x = 1}"> x es igual a 1 </c:when> <c:when test="${x = 2}"> x es igual a 2 </c:when> <c:otherwise> x es diferente de 1 y 2 </c:otherwise> </c:choose> <c:foreach> Realiza repeticiones, evaluando su cuerpo en cada iteración. var : variable que contiene el objeto de la iteración en curso. Al menos debe estar presente uno de los siguientes grupos de atributos: items : expresión que se evalúa a un objeto iterable (mapa, colección o arreglo). begin : expresión de inicio de iteración. end : expresión de fin de iteración. step : incremento (opcional, default [Capítulo 9] Página 185

186 EL Y JSTL = 1). Ejemplo: <c:foreach var="i" begin="1" end="10"> ${i} </c:foreach> Estado HTTP PROBLEMAS CON JSTL type Informe de Excepciï ½n mensaje descripciï ½n El servidor encontrï ½ un error interno () que hizo que no pudiera rellenar este requerimiento. excepciï ½n org.apache.jasper.jasperexception: /jstl_out-1.jsp(7,4) Segï ½n el TLD o la directiva attribute del archivo tag, el atributo value no acepta expresiones org.apache.jasper.compiler.defaulterrorhandler.jsperror(defaulterrorhandl er.java:40) org.apache.jasper.compiler.errordispatcher.dispatch(errordispatcher.java: 407) org.apache.jasper.compiler.errordispatcher.jsperror(errordispatcher.java: 148) org.apache.jasper.compiler.validator$validatevisitor.checkxmlattributes(v alidator.java:1174) org.apache.jasper.compiler.validator$validatevisitor.visit(validator.java :821) org.apache.jasper.compiler.node$customtag.accept(node.java:1512) org.apache.jasper.compiler.node$nodes.visit(node.java:2343) org.apache.jasper.compiler.node$visitor.visitbody(node.java:2393) org.apache.jasper.compiler.node$visitor.visit(node.java:2399) org.apache.jasper.compiler.node$root.accept(node.java:489) org.apache.jasper.compiler.node$nodes.visit(node.java:2343) org.apache.jasper.compiler.validator.validate(validator.java:1739) org.apache.jasper.compiler.compiler.generatejava(compiler.java:166) org.apache.jasper.compiler.compiler.compile(compiler.java:315) org.apache.jasper.compiler.compiler.compile(compiler.java:295) org.apache.jasper.compiler.compiler.compile(compiler.java:282) org.apache.jasper.jspcompilationcontext.compile(jspcompilationcontext.jav a:586) org.apache.jasper.servlet.jspservletwrapper.service(jspservletwrapper.jav a:317) org.apache.jasper.servlet.jspservlet.servicejspfile(jspservlet.java:342) org.apache.jasper.servlet.jspservlet.service(jspservlet.java:267) javax.servlet.http.httpservlet.service(httpservlet.java:717) com.ingrac.servlets.empleadoservlet.dopost(empleadoservlet.java:24) javax.servlet.http.httpservlet.service(httpservlet.java:637) javax.servlet.http.httpservlet.service(httpservlet.java:717) [Capítulo 9] Página 186

187 EL Y JSTL nota La traza completa de la causa de este error se encuentra en los archivos de diario de Apache Tomcat/ Apache Tomcat/ Para correr todas las pruebas de los ejemplos aquí mostrados se utilizó como Contenedor Web el Tomcat versión Al momento de ejecutar nuestra JSP se puede dar el caso de obtener el error que aparece arriba. Ese error se obtiene cuando en tu JSP tienes: <%@ taglib prefix="c" uri=" %> <html> <head> <title>jstl</title> </head> <body> <c:out value="empleado: ${empleado.nombre}" /> </body> </html> En vez de lo sig: <%@ taglib prefix="c" uri=" %> <html> <head> <title>jstl</title> </head> <body> <c:out value="empleado: ${empleado.nombre}" /> </body> </html> [Capítulo 9] Página 187

188 EL Y JSTL Si notas la diferencia en la parte sombreada? La falta de "jsp" en la uri implica que se esta usando JSTL 1.0, en el cuál en los atributos no se admitían expresiones, y no funcionaba. uri=" %> uri=" %> [Capítulo 9] Página 188

189 TAGS PERSONALIZADOS Capítulo 10 TAGS PERSONALIZADOS [Capítulo 10] Página 189

190 TAGS PERSONALIZADOS OBJETIVOS DEL EXAMEN Sección 10: Construir una Librería Tag Personalizada Describe la semántica del modelo de evento tag personalizado "Classic" cuando cada método del evento (dostarttag, doafterbody y doendtag) es ejecutado y explica lo que significa el valor de regreso para cada método del evento; y escribe la clase manejadora de tag. Usando la API de PageContext, escribe código de manejador de tag para acceder a las variables implícitas de la JSP y acceder a los atributos de la aplicación Web. Dado un escenario, escribe el código del manejador de tag para acceder al tag padre y un tag ancestro arbitrario. Describe la semántica del modelo de evento tag personalizado "Simple" cuando el método de evento (dotag) es ejecutado; escribe la clase manejadora de tag y explica las restricciones en el contenido de la JSP dentro del tag. Describe la semántica del modelo de archivo tag; describe la estructura de la aplicación Web para archivos tag; escribe un archivo tag y explica las restricciones en el contenido de la JSP en el cuerpo del tag. [Capítulo 10] Página 190

191 TAGS PERSONALIZADOS INTRODUCCIÓN En muchas ocasiones nos gustaría poder extender nuestra JSP proporcionando mayor funcionalidad. Hay quienes encapsulan las etiquetas (tags) HTML para hacer una especie de tag personalizado pero en realidad no estan ampliando la función de esa etiqueta que en sí ya hace algo especifico. Por ejemplo: <html> <body> <form method="post" action="employee"> <input type="submit" /> </form> </body> </html> Encapsulado: <myhtml> <mybody> <myform method="post" action="employee"> <myinput type="submit" /> </myform> </mybody> </myhtml> En un momento dado lo que queremos como desarrolladores es poder crear nuestros propios tags. Bueno pues eso es lo que precisamente hacen los Tags Personalizados. Pero no solo es crear el tag para decir es mío, "es mi tag", sino hay otra razón más fuerte. Cuando uno utiliza <jsp:include> o <c:import> uno agrega el contenido de otra pagina dinámicamente. Y también puedes fijar nuevos parámetros de petición en esas páginas para poder utilizarlos. [Capítulo 10] Página 191

192 TAGS PERSONALIZADOS ARCHIVOS TAG Con los archivos tag tu puedes incluir el contenido de una pagina JSP igual como lo hacen <jsp:include> o <c:import>. Con la versión 2.0 de JSP el compilador reconoce los archivos tag. Un archivo tag es un archivo fuente que provee una forma de abstraer un segmento de código JSP y hacerlo reutilizable por medio de una acción personalizada. La extensión del archivo requerida para un archivo tag son:.tag.tagx EJEMPLO: Si tengo una JSP llamada titulo.jsp que contiene lo siguiente: <hr /> <center><h1>titulo</h1></center> <hr /> Le cambio el nombre de la extensión a.tag o.tagx: titulo.jsp titulo.tag o titulo.jsp titulo.tagx [Capítulo 10] Página 192

193 TAGS PERSONALIZADOS Este nuevo archivo se pone dentro de /WEB-INF/tags/ WEB-INF tags titulo.tag La JSP que llama a este nuevo archivo (titulo.tag): <%@ taglib prefix="mitag" tagdir="/web-inf/tags" %> <html> <head> <title>archivos Tag</title> </head> <body> <mitag:titulo /> AQUI VA EL CUERPO DE LA JSP... </body> </html> Resultado: [Capítulo 10] Página 193

194 TAGS PERSONALIZADOS La directiva taglib le indica a la JSP que usa una librería de etiquetas (tag library). Esta librería se identifica de manera única usando un URI (Universal Resource Identifier) y asocia un prefijo para su uso. Una librería de etiquetas (tag library) es una colección de acciones que encapsulan cierta funcionalidad que va a ser usada dentro de una JSP. Esta librería queda disponible para la JSP por medio de la directiva taglib. Las acciones estándar: <jsp:invoke> <jsp:dobody> solo pueden ser usadas en archivos tag. [Capítulo 10] Página 194

195 TAGS PERSONALIZADOS DIRECTIVAS DE LOS ARCHIVOS TAG A continuación se muestran las directivas disponibles dentro de los archivos tag. DIRECTIVA DISPONIBLE? INTERPRETACIÓN/RESTRICCIÓN page no Un archivo tag no es una pagina. Si se usa en un archivo tag, resultará un error de traducción. En vez de esta se debe usar la directiva tag. taglib si Idéntico a las paginas JSP. include si Idéntico a las paginas JSP. Si el archivo incluido contiene sintaxis no permitida por el archivo tag, entonces ocurrirá un error de traducción. tag si Solo se aplica en archivos tag. Si se intenta usar esta directiva en una página JSP resultará en un error de traducción. attribute si Solo se aplica en archivos tag. Si se intenta usar esta directiva en una página JSP resultará en un error de traducción. variable si Solo se aplica en archivos tag. Si se intenta usar esta directiva en una página JSP resultará en un error de traducción. [Capítulo 10] Página 195

196 TAGS PERSONALIZADOS RECORDATORIO: Cuando utilizamos <jsp:include> para enviar parámetros dentro de esta acción se usa <jsp:param>. EJEMPLO: Si tenemos la sig. JSP. titulo.jsp: <hr /> <center><h1>titulo</h1></center> <hr /> <center>${param.subtitulo}</center> <hr /> prueba.jsp: <html> <body> <jsp:include page="titulo.jsp"> <jsp:param name="subtitulo" value="sub" /> </jsp:include> </body> </html> Resultado: [Capítulo 10] Página 196

197 TAGS PERSONALIZADOS prueba.jsp fija el valor de SUB para el parámetro subtitulo el cual puede ser usado por titulo.jsp, como cualquier otro parámetro de petición. Pero para un Archivo Tag tú no envías parámetros de petición, envías atributos tag. Rehaciendo el ejemplo anterior: titulo.tag: attribute name="subtitulo" required="true" rtexprvalue="true" %> <hr /> <center><h1>titulo</h1></center> <hr /> <center>${subtitulo}</center> <hr /> prueba.jsp: taglib prefix="mitag" tagdir="/web-inf/tags" %> <html> <body> <mitag:titulo subtitulo="sub" /> </body> </html> Resultado: [Capítulo 10] Página 197

198 TAGS PERSONALIZADOS Qué pasa si el valor del atributo es muy grande? Si el valor del atributo es muy grande entonces utiliza: <jsp:dobody /> titulo.tag: <hr /> <center><h1>titulo</h1></center> <hr /> <center><jsp:dobody /></center> <hr /> prueba.jsp: taglib prefix="mitag" tagdir="/web-inf/tags" %> <html> <body> <mitag> Este subtitulo se puede considerar <br /> bastante largo.<br /> Por lo tanto, se usa <jsp:dobody /> </mitag> </body> </html> Resultado: [Capítulo 10] Página 198

199 SEGURIDAD Capítulo 11 SEGURIDAD [Capítulo 11] Página 199

200 SEGURIDAD OBJETIVOS DEL EXAMEN Sección 5: Seguridad de la Aplicación Web Basado en la especificación del servlet, compara y contrasta los siguientes mecanismos de seguridad: (a) autenticación, (b) autorización, (c) integridad de datos y (d) confidencialidad. En el descriptor de despliegue (web.xml), declara una restricción de seguridad, un recurso Web, la garantía de transporte, la configuración de login y un rol de seguridad. Compara y contrasta los tipos de autenticación (BASIC, DIGEST, FORM y CLIENT-CERT); describe como trabaja; y dado un escenario, selecciona el tipo apropiado. [Capítulo 11] Página 200

201 SEGURIDAD INTRODUCCIÓN Para efectos de seguridad existen 4 conceptos básicos: AUTENTICACION (AUTHENTICATION) AUTORIZACION (AUTORIZATION) INTEGRIDAD DE DATOS (DATA INTEGRITY) CONFIDENCIALIDAD (CONFIDENTIALITY) AUTENTICACION Si eres realmente quien dices ser. La autenticación se relaciona a los nombres de usuario y contraseñas. De aquí surge otro concepto llamado REALM. REALM es donde la autenticación es almacenada. Para habilitar la autenticación en nuestra aplicación web recurrimos a nuestro DD (web.xml): <web-app...>... <login-config> <auth-method>basic</auth-method> </login-config>... </web-app> [Capítulo 11] Página 201

202 SEGURIDAD AUTORIZACIÓN Una vez autenticado se verifica a qué recursos puedes acceder. 1) Mapear usuarios del servidor a la aplicación. SERVIDOR <tomcat-users> <role-name>admin</role-name> <role-name>miembro</role-name> <role-name>invitado</role-name> <user name="juan" password="perez" roles="admin,guest" </tomcat-users> APLICACION <web-app...>... <security-role> <role-name>admin</role-name> <role-name>miembro</role-name> <role-name>invitado</role-name> </security-role>... </web-app> 2) Restringir el acceso a los recursos. <web-app...>... <security-constraint> <web-resource-collection> <web-resource-name> NombreObligatorio </web-resource-name> <url-pattern>/x/y/*</url-pattern> <url-pattern>/x/z/*</url-pattern> <http-method>post</http-method> <http-method>get</http-method> </web-resource-collection> <auth-constraint> <role-name>miembro</role-name> </auth-constraint> </security-constraint>... </web-app> [Capítulo 11] Página 202

203 SEGURIDAD REGLAS PARA <web-resource-collection>: <web-resource-name> es OBLIGATORIO <url-pattern> puede haber UNO o MÁS. Pero al menos debe haber uno. <http-method> puede haber CERO o MÁS. Si no se pone entonces se asume que se aplica a todos los métodos http. REGLAS PARA <auth-constraint>: <auth-constraint> es OPCIONAL. Si no se pone entonces se asume que se aplica a todos los roles. <auth-constraint /> significa que no se aplica a ningún rol. <role-name> puede haber UNO o MÁS. <role-name>*</role-name> significa que se aplica a todos los roles. Es lo mismo que si no se pusiera <authconstraint>. [Capítulo 11] Página 203

204 SEGURIDAD EJEMPLO: Vamos a suponer que queremos entrar a una feria y al momento de comprar nuestro boleto resulta que hay 3 tipos: 1. TOTAL 2. MEDIO 3. BASICO El primero permite el acceso a todos los juegos de la feria y todos los espectáculos. El segundo solo te permite el acceso a los juegos, no incluye espectáculos. El tercero solo te permite el acceso a 20 juegos de los 50 que hay. Por lo tanto, TOTAL, MEDIO y BASICO, te permiten la entrada a la feria (AUTENTICACION). Dependiendo del nombre del boleto es el acceso a cierto tipo de juegos y espectáculos (AUTORIZACION). Aplicando lo anterior a un sistema nos dice que cualquier usuario valido (usuario y contraseña validas en el sistema) puede ingresar al sistema. Pero no todos los usuarios tienen acceso a todos los datos o a realizar modificaciones en el sistema. Es más su acceso podría estar restringido en el mismo menú. [Capítulo 11] Página 204

205 SEGURIDAD SEGURIDAD DECLARATIVA Se refiere a aplicar la estructura de seguridad de la aplicación de una forma externa. El Descriptor de Despliegue (DD) es la vía principal para este tipo de seguridad. SEGURIDAD PROGRAMÁTICA Hay ocasiones que en el código encontramos condiciones para poder ejecutar o no cierta sección de nuestro programa. Esto no es bueno porque estamos suponiendo la existencia de cierto rol en el sistema de seguridad. Por otro lado, lo que tanto se critica a los programadores hardcode. Con lo anterior estamos hardcodeando nuestra suposición. request.getremoteuser(); // se refiere a autenticación request.isuserinrole( ADM ); // se refiere a autorización Para estos casos necesitamos mapear, el rol que se escribió en el programa con el rol que existe en nuestro esquema de seguridad. Se hace de la sig. forma: <web-app...>... <servlet> <servlet-name>admin</servlet-name> <servlet-class>miembro</servlet-class> <security-role-ref> <role-name>adm</role-name> <role-link>admin</role-link> </security-role-ref> </servlet>... </web-app> [Capítulo 11] Página 205

206 SEGURIDAD <auth-method> La sig. tabla muestra los valores que puede tener <auth-method>: TIPO ESPECIFICACION INTEGRIDAD DE DATOS COMENTARIOS BASIC HTTP Base64, es débil Todos los navegadores lo soportan DIGEST HTTP Es más fuete pero no usa SSL Es opcional para HTTP y J2EE FORM J2EE Muy débil no utiliza encriptación Permite a los usuarios tener una pantalla de login personalizada CLIENT- CERT J2EE Es fuerte, necesita un certificado de llave pública (PKC) Los usuarios necesitan un certificado <auth-method>form</auth-method> Si el método de autenticación es FORM entonces tenemos lo sig: <web-ap...>... <login-config> <auth-method>form</auth-method> <form-login-config> <form-login-page>/login.html<form-login-page> <form-error-page>/error.html<form-error-page> </form-login-config> </login-config>... </web-app> login.html: <html> <head> <title>login</title> </head> <body> <form method= post action= j_security_check > <input type= text name= j_username /> <input type= password name= j_password /> <input type= submit /> </form> </body> </html> [Capítulo 11] Página 206

207 SEGURIDAD error.html <html> <head> <title>error</title> </head> <body> ERROR </body> </html> INTEGRIDAD DE DATOS La integridad de datos se refiere a que sin importar que pase los datos no va a ser modificados. CONFIDENCIALIDAD La confidencialidad se refiere a que los datos no pueden ser vistos. <web-app...>... <security-constraint>... <user-data-constraint> <transport-guarantee>integral</transport-guarantee> </user-data-constraint>... </security-constraint>... </web-app> ROLES Un rol es un grupo lógico de usuarios definidos por el Desarrollador de la Aplicación o por Ensamblador. Cuando la aplicación es desplegada, los roles son mapeados por el Desplegador de la Aplicación. [Capítulo 11] Página 207

208 PATRONES DE DISEÑO Capítulo 12 PATRONES DE DISEÑO [Capítulo 12] Página 208

209 PATRONES DE DISEÑO Sección 11: Patrones Java EE OBJETIVOS DEL EXAMEN Dada una descripción de un escenario con una lista de problemas, selecciona un patrón que pueda resolver el problema. La lista de patrones que debes conocer es: Intercepting Filter, Model-View-Controller, Front Controller, Service Locator, Business Delegate, y Transfer Object. Encaja patrones de diseño con declaraciones describiendo beneficios potenciales que aumente desde el uso del patrón para cualquiera de los siguientes patrones: Intercepting Filter, Model-View-Controller, Front Controller, Service Locator, Business Delegate, y Transfer Object. [Capítulo 12] Página 209

210 PATRONES DE DISEÑO INTRODUCCIÓN Un Patrón de Diseño es la solución a un problema recurrente. En nuestro desarrollo profesional como programadores y desarrolladores siempre nos vemos en la situación de tener que resolver algún problema. En muchas ocasiones los problemas que tenemos que resolver ya fueron resueltos por alguien más. Un patrón debe explicar por que una situación en particular causa problemas y porque la solución propuesta es considerada como la mejor. HISTORIA La idea original fue introducida por Christopher Alexander. Nacido el 4 de Octubre de 1936 en Viena. Arquitecto conocido por sus teorías sobre diseño y por más de 200 proyectos de construcción en California, Japón, México y alrededor del mundo. Hizo el razonamiento de que los usuarios saben más sobre los edificios que necesitan que los mismos arquitectos, él produjo y validó (en colaboración con Sarah, Ishikawa y Murray Silverstein) un lenguaje de patrón. El es ampliamente conocido como el padre del movimiento del lenguaje de patrón en las ciencias computacionales. La idea del lenguaje de patrón aparece para aplicarse a cualquier tarea compleja de ingeniería. Ha influido en la ingeniería de software donde los patrones han sido usados para documentar el conocimiento colectivo en el campo. The Gang of Four (GoF), son el grupo conformado por Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides y creadores del libro: Design Patterns: Elements of Reusable Object-Oriented Software. La publicación original del libro fue el 21 de Octubre de 1994, con copyright en [Capítulo 12] Página 210

211 PATRONES DE DISEÑO En su libro clasifican los patrones en tres categorías: Patrones de Creación Estos patrones tienen que ver con la instanciacion de las clases. Se pueden dividir en patrones de creación de clases y patrones de creación de objetos. Los patrones de creación de clases usan herencia en su proceso de instanciacion. Los patrones de creación de objetos usan delegación. Abstract Factory Builder Factory Method Prototype Singleton Patrones Estructurales Se refieren a composición. Usan herencia para crear interfases y definir formas de crear objetos para obtener nuevas funcionalidades. Adapter Bridge Composite Decorator Façade Flyweight Proxy [Capítulo 12] Página 211

212 PATRONES DE DISEÑO Patrones de Comportamiento Se refiere a la comunicación entre objetos. Chain of Responsibility Command Interpreter Iterator Mediator Memento Observer State Strategy Template Method Visitor En total mencionan 23 patrones. Que por cierto, no están incluidos en el examen... que buena broma haberlos mencionado no? Pues no fue broma, en realidad lo hice para que tuvieras un breve antecedente. Para el examen solo necesitas conocer 6: Model-View-Controller Intercepting Filter Front Controller Transfer Object Business Delegate Service Locator Así se menciona en los objetivos. Te presentaran escenarios y tendrás que elegir el patrón que mejor se adapte. [Capítulo 12] Página 212

213 PATRONES DE DISEÑO Pero como puedes observar los patrones que vienen en el examen no son mencionados por GoF. Esto es porque a pesar de que los patrones de GoF sirvieron para el diseño y desarrollo de sistemas orientados a objetos en ambientes distribuidos y no distribuidos, no fueron pensados para sistemas empresariales de gran escala. La necesidad obligó a los arquitectos a documentar soluciones a problemas recurrentes debido a que experimentaban el mismo problema una y otra vez. Comenzaron extendiendo y refinando los patrones. Un libro que documenta alrededor de 30 patrones es CORBA Design Patterns por Thomas J. Mowbray y Rápale C. Malveau. A pesar de que el libro se enfoca en CORBA (Common Object Request Broker Architecture), los patrones descritos se pueden aplicar a aplicaciones distribuidas, incluyendo aquellas que no usan CORBA. [Capítulo 12] Página 213

214 PATRONES DE DISEÑO PATRONES J2EE Ya que J2EE conforma una arquitectura que incluye Servlets, JSPs, EJBs, etc., merece su propio conjunto de patrones. PATRONES DE DISEÑO PARA EL EXAMEN Modelo Vista Controlador (MVC) A este patrón de diseño también se le llama Modelo 2. La esencia de este modelo es que separa la lógica de negocio de la presentación. De esta forma la lógica de negocio puede usarse como una clase de java reutilizable y ni siquiera saber que existe la vista. La arquitectura MVC tiene sus raíces en Smalltalk, donde originalmente fue aplicada para mapear las tradicionales tareas de entrada, procesamiento y salida al modelo de interacción grafico de usuario. Sin embargo, es directo mapear estos conceptos dentro del dominio de aplicaciones empresariales multi-capas. Un simple diagrama se muestra a continuación: Controller Model BD View [Capítulo 12] Página 214

215 PATRONES DE DISEÑO Se aplica en situaciones donde la misma información (Modelo) es presentada en diferentes formatos (Vista), pero es administrada centralmente por una sola entidad de control (Controlador). En muchas ocasiones se menciona como arquitectura MVC o patrón MVC. Qué es en realidad Arquitectura o Patrón? Es ambos. Arquitectura o patrón dependiendo donde se use. FLUJO 1. El usuario interactúa con la interfase de alguna forma (por ejemplo, oprime un botón). 2. Un controlador manipula el evento de entrada de la interfase de usuario, frecuentemente por medio de un manejador. 3. El controlador notifica al modelo de la acción del usuario, posiblemente resultando en un cambio en el estado del modelo (Por ejemplo, si el controlador actualiza el contenido de un carrito de compras). 4. Una vista utiliza el modelo (indirectamente) para generar una interfase de usuario apropiada (por ejemplo, la vista produce una pantalla listando el contenido del carrito de compras). La vista obtiene su propia información del modelo. El modelo no tiene conocimiento directo de la vista. 5. La interfase de usuario espera para futuras interacciones, con lo cual se inicia el ciclo nuevamente. [Capítulo 12] Página 215

216 PATRONES DE DISEÑO VISTA: Es responsable de la presentación. Obtiene el estado del modelo desde el Controlador (aunque no directamente; el Controlador pone los datos del modelo para que la vista pueda encontrarlo). Es también la parte que obtiene los datos de entrada del usuario que van al Controlador. CONTROLADOR: Toma los datos de entrada del usuario desde la petición y obtiene el significado para el modelo. Le dice al modelo que se actualice y hace que el nuevo modelo quede disponible para la vista (la JSP). MODELO: Tiene la lógica de negocio real y el estado. En otras palabras conoce las reglas para fijar y actualizar el estado. Es la única parte del sistema que interactúa con la base de datos (aunque probablemente use otro objeto para comunicarse con la BD). VENTAJAS Y DESVENTAJAS: Reutilización de los componentes del modelo. La separación del modelo de la vista permite a diferentes vistas usar el mismo modelo. En consecuencia, los componentes del modelo de la aplicación empresarial son más fáciles de implementar, probar y mantener, ya que todos los accesos al modelo van a través de estos componentes. Más fácil soporte para nuevos tipos de clientes. Para soportar un nuevo tipo de cliente tú simplemente escribes una vista y algo de lógica para el controlador y los unes dentro de la aplicación empresarial existente. Aumenta la complejidad del diseño. Este patrón introduce algo de clases extra debido a la separación del modelo, vista y controlador. [Capítulo 12] Página 216

217 PATRONES DE DISEÑO Ejemplo: Vamos a ver el caso más sencillo que pudiéramos tener. En una pagina inicial HTML, simplemente tendríamos un campo de texto para escribir un nombre y el botón de SUBMIT para enviar la forma. En respuesta nos regresaría otra pantalla con el "HOLA NOMBRE". Utilizando MVC. Solución: Controlador.java Controller nombre.html Model Modelo.java vista.jsp BD View nombre.html: <html> <head> <title>mvc</title> </head> <body> <form method="post" action="name"> Nombre: <input type="text" name="nombre" /> <input type="submit" /> </form> </body> </html> [Capítulo 12] Página 217

218 PATRONES DE DISEÑO Modelo.java: package com.model; public class Modelo { } public String getnombre(string nombre) { return nombre; } Controlador.java: package com.controller; import java.io.ioexception; import javax.servlet.requestdispatcher; import javax.servlet.servletexception; import javax.servlet.http.httpservlet; import javax.servlet.http.httpservletrequest; import javax.servlet.http.httpservletresponse; import com.model.modelo; public class Controlador extends HttpServlet { public void dopost(httpservletrequest request, HttpServletResponse response) throws ServletException, IOException { Modelo modelo = new Modelo(); String nombre = request.getparameter("nombre"); request.setattribute("name", nombre); } } RequestDispatcher view = request.getrequestdispatcher("/vista.jsp"); view.forward(request, response); [Capítulo 12] Página 218

219 PATRONES DE DISEÑO web.xml <web-app...> <servlet> <servlet-name>controlador</servlet-name> <servlet-class>com.controller.controlador</servlet-class> </servlet> <servlet-mapping> <servlet-name>controlador</servlet-name> <url-pattern>/name</url-pattern> </servlet-mapping> </web-app> vista.jsp <html> <head> <title>vista</title> </head> <body> HOLA ${name} </body> </html> Esta es la pantalla inicial, en este ejemplo utilizamos una simple pagina HTML, pero bien pudo haber sido una pagina JSP. [Capítulo 12] Página 219

220 PATRONES DE DISEÑO A continuación escribimos un nombre en el campo de texto: Finalmente después de oprimir el botón "Enviar consulta", obtendremos la sig. pantalla: [Capítulo 12] Página 220

221 PATRONES DE DISEÑO PUNTOS CLAVE DE EXAMEN MVC Pon atención especial al observar las sig. palabras, frases o términos en los escenarios que te plantean en el examen: Separación en la presentación de datos y representación de datos. Provee servicios a diferentes clientes: cliente web, cliente WAP, etc. Múltiples vistas, tales como HTML o WML. También se podría mencionar por ahí SWING. Un solo controlador. Minimiza el impacto al realizar cambios entre capas. Las vistas pueden cambiar independientemente de los controladores y modelos. Los modelos ocultan sus detalles internos de la vista y del controlador. [Capítulo 12] Página 221

222 PATRONES DE DISEÑO Intercepting Filter Este patrón es capaz de interceptar las peticiones provenientes del cliente antes de que lleguen al servlet. Y también puede interceptar las respuestas provenientes del servlet antes de que lleguen al cliente. Cliente Contenedor Filtro Este patrón puede pre-procesar o redireccionar peticiones y puede post-procesar o reemplazar el contenido de las respuestas. [Capítulo 12] Página 222

envía al browser. El browser despliega el archivo.

envía al browser. El browser despliega el archivo. SERVLETS Dr. Raúl Perez Páginas web estáticas Como se despliega una página web en un browser Normalmente la página se crea usando HTML y se almacena como un archivo en el servidor de web. El usuario escribe

Más detalles

NIVEL 16: ESTRUCTURAS N-ARIAS RECURSIVAS Aplicaciones Web, Html y Servlets. ISIS1206 Estructuras de Datos http://cupi2.uniandes.edu.

NIVEL 16: ESTRUCTURAS N-ARIAS RECURSIVAS Aplicaciones Web, Html y Servlets. ISIS1206 Estructuras de Datos http://cupi2.uniandes.edu. 1 NIVEL 16: ESTRUCTURAS N-ARIAS RECURSIVAS Aplicaciones Web, Html y Servlets 2 Agenda Protocolo HTTP Formas HTML Servlets 3 Protocolo HTTP Hypertext Transfer Protocol (HTTP) - 1990 Versión 1.1 Mecanismo

Más detalles

Requisitos. Universidad ORT Arquitectura de Software

Requisitos. Universidad ORT Arquitectura de Software Requisitos Java Development Kit (JDK) 1.5 o superior NetBeans IDE 6.5 o superior JBoss Application Server 4.2.x o 5.x.x Variable de entorno JAVA_HOME apuntando al directorio de instalación de la JDK 1

Más detalles

Capitulo 5. Implementación del sistema MDM

Capitulo 5. Implementación del sistema MDM Capitulo 5. Implementación del sistema MDM Una vez que se concluyeron las actividades de análisis y diseño se comenzó la implementación del sistema MDM (Manejador de Documentos de MoProSoft). En este capitulo

Más detalles

Web Tier en JAVA. Nicolás Troncoso Carrère. Valparaíso, 2006. ILI 258 Departamento de Informática Universidad Técnica Federico Santa María

Web Tier en JAVA. Nicolás Troncoso Carrère. Valparaíso, 2006. ILI 258 Departamento de Informática Universidad Técnica Federico Santa María Nicolás Troncoso Carrère ILI 258 Departamento de Informática Universidad Técnica Federico Santa María Valparaíso, 2006 1 2 3 Porqué paginas dinamicas? Confirmacion de suscripciones. Contenido generado

Más detalles

Figura 7-1 Enlace para instalar el servidor web Apache Jakarta Tomcat 4.1.12.

Figura 7-1 Enlace para instalar el servidor web Apache Jakarta Tomcat 4.1.12. Unidad 7 Servlets 7.1 Marco teórico Lo que permite que ordenadores remotos con procesadores y sistemas operativos diferentes se entiendan y en definitiva que Internet funcione como lo hace en la actualidad,

Más detalles

Un servlet es una clase java que implementa la Servlet interface. Un servlet corre dentro de un contexto denominado Servlet engine.

Un servlet es una clase java que implementa la Servlet interface. Un servlet corre dentro de un contexto denominado Servlet engine. Capítulo 6 Servlets En esta sección se va a tratar el primer componente que corre del lado del servidor, y es uno de los puntos fundamentales para la comunicación entre el cliente (browser) y el servidor.

Más detalles

Capítulo 3 Diseño del Sistema de Administración de Información de Bajo Costo para un Negocio Franquiciable

Capítulo 3 Diseño del Sistema de Administración de Información de Bajo Costo para un Negocio Franquiciable Capítulo 3 Diseño del Sistema de Administración de Información de Bajo Costo para un Negocio Franquiciable 1. Introducción. El Sistema de Administración de Información de un Negocio Franquiciable (SAINF)

Más detalles

Curso de PHP con MySQL Gratis

Curso de PHP con MySQL Gratis Curso de PHP con MySQL Gratis Introducción Este mini curso o mini tutorial de PHP le ayudará a realizar cualquier sistema para que pueda insertar uno o varios registros a una base de datos con MySQL, este

Más detalles

JAVA EE 5. Arquitectura, conceptos y ejemplos.

JAVA EE 5. Arquitectura, conceptos y ejemplos. JAVA EE 5. Arquitectura, conceptos y ejemplos. INTRODUCCIÓN. MODELO DE LA APLICACIÓN JEE5. El modelo de aplicación Java EE define una arquitectura para implementar servicios como lo hacen las aplicaciones

Más detalles

USANDO SERVLETS EN UN SERVIDOR WEB RESIN

USANDO SERVLETS EN UN SERVIDOR WEB RESIN USANDO SERVLETS EN UN SERVIDOR WEB RESIN Servidor Web Resin Resin es un servidor web que permite no solo despachar un página web, sino aplicaciones web construidos bajo la arquitectura J2EE, así como el

Más detalles

ISJu: Técnicas de Programación Cartilla Teórica-Práctica 2014. Instalación del "Eclipse IDE for Java EE Developers" y el servidor "Apache Tomcat"

ISJu: Técnicas de Programación Cartilla Teórica-Práctica 2014. Instalación del Eclipse IDE for Java EE Developers y el servidor Apache Tomcat Unidad 6: Servlets Instalación del "Eclipse IDE for Java EE Developers" y el servidor "Apache Tomcat" "Eclipse IDE for Java EE Developers" Para desarrollar aplicaciones que se ejecuten en un servidor web

Más detalles

[CASI v.0109] Pág. 1

[CASI v.0109] Pág. 1 I. DATOS INFORMATIVOS Carrera Especialidad Curso Código Ciclo : COMPUTACIÓN E INFORMATICA : Ingeniería de Software : Lenguaje de Programación II : F-INF110 : Cuarto Requisitos : T-INF108 (Lenguaje de Programación

Más detalles

INTRODUCCION. Tema: Protocolo de la Capa de aplicación. FTP HTTP. Autor: Julio Cesar Morejon Rios

INTRODUCCION. Tema: Protocolo de la Capa de aplicación. FTP HTTP. Autor: Julio Cesar Morejon Rios INTRODUCCION Tema: Protocolo de la Capa de aplicación. FTP HTTP Autor: Julio Cesar Morejon Rios Qué es FTP? FTP (File Transfer Protocol) es un protocolo de transferencia de archivos entre sistemas conectados

Más detalles

MANUAL DE USUARIO DE CUENTAS DE CORREO

MANUAL DE USUARIO DE CUENTAS DE CORREO MANUAL DE USUARIO DE CUENTAS DE CORREO Existen dos formas de consultar el correo, por Interfaz Web (Webmail), la cual se realiza desde un navegador de Internet, o mediante un cliente de Correo, tal como

Más detalles

AGREGAR COMPONENTES ADICIONALES DE WINDOWS

AGREGAR COMPONENTES ADICIONALES DE WINDOWS INSTALACIÓN DE IIS EN WINDOWS XP El sistema está desarrollado para ejecutarse bajo la plataforma IIS de Windows XP. Por esta razón, incluimos la instalación de IIS (Servidor de Web) para la correcta ejecución

Más detalles

Servlets. Unidad: 4 Laboratorio de Programación. Universidad Nacional de la Patagonia Austral Unidad Académica Río Gallegos

Servlets. Unidad: 4 Laboratorio de Programación. Universidad Nacional de la Patagonia Austral Unidad Académica Río Gallegos Servlets Unidad: 4 Laboratorio de Programación Universidad Nacional de la Patagonia Austral Unidad Académica Río Gallegos Indice Introducción CGI Servlets: concepto, caracteristicas Servlets Vs. CGI Ciclo

Más detalles

Guía rápida de instalación Cámara CCTV-210

Guía rápida de instalación Cámara CCTV-210 Guía rápida de instalación Cámara CCTV-210 Ya conecté la cámara a mi MODEM, pero no veo nada. Qué puedo hacer? A continuación damos una guía sencilla y rápida para instalar las cámara dentro de una red

Más detalles

Acronis License Server. Guía del usuario

Acronis License Server. Guía del usuario Acronis License Server Guía del usuario TABLA DE CONTENIDO 1. INTRODUCCIÓN... 3 1.1 Generalidades... 3 1.2 Política de licencias... 3 2. SISTEMAS OPERATIVOS COMPATIBLES... 4 3. INSTALACIÓN DE ACRONIS LICENSE

Más detalles

La utilización de las diferentes aplicaciones o servicios de Internet se lleva a cabo respondiendo al llamado modelo cliente-servidor.

La utilización de las diferentes aplicaciones o servicios de Internet se lleva a cabo respondiendo al llamado modelo cliente-servidor. Procesamiento del lado del servidor La Programación del lado del servidor es una tecnología que consiste en el procesamiento de una petición de un usuario mediante la interpretación de un script en el

Más detalles

Internet Information Server

Internet Information Server Internet Information Server Internet Information Server (IIS) es el servidor de páginas web avanzado de la plataforma Windows. Se distribuye gratuitamente junto con las versiones de Windows basadas en

Más detalles

TUTORIAL PARA CREAR UN SERVIDOR FTP

TUTORIAL PARA CREAR UN SERVIDOR FTP TUTORIAL PARA CREAR UN SERVIDOR FTP A continuación ustedes podrán observar y luego implementar el informe que elaboré a fin de que TODOS puedan aprender a montar y mantener su propio Servidor FTP. Comenzaremos

Más detalles

Facultad de Ingeniería Escuela de Ciencias y Sistemas 2011-14674 Estructura de Datos Guatemala 2013 JSF + JSP + RichFaces

Facultad de Ingeniería Escuela de Ciencias y Sistemas 2011-14674 Estructura de Datos Guatemala 2013 JSF + JSP + RichFaces JSF + JSP + RichFaces Manual Introductorio al uso de JSF, JSP y RichFaces en Java El siguiente documento es un manual muy introductorio, ya que la primera vez que me encontré con estas 3 frases juntas

Más detalles

INFORMÁTICA IE. Términos a conocer y conceptos básicos. World Wide Web (WWW):

INFORMÁTICA IE. Términos a conocer y conceptos básicos. World Wide Web (WWW): INFORMÁTICA IE MÓDULO INTERNET Términos a conocer y conceptos básicos World Wide Web (WWW): Digamos, simplemente, que es un sistema de información, el sistema de información propio de Internet. Sus características

Más detalles

Modelo de Objetos Distribuidos

Modelo de Objetos Distribuidos Remote Method Invocation Modelo de Objetos Distribuidos Un objeto remoto es un objeto cuyos métodos pueden ser invocados desde otra máquina virtual de java, potencialmente en un host diferente. Modelo

Más detalles

Comisión Nacional de Bancos y Seguros

Comisión Nacional de Bancos y Seguros Comisión Nacional de Bancos y Seguros Manual de Usuario Capturador de Pólizas División de Servicios a Instituciones Financieras Mayo de 2011 2 Contenido 1. Presentación... 3 1.1 Objetivo... 3 2. Descarga

Más detalles

Practica 1 Instalación del SGBD. Ing. María Elena Reyes Castellanos. Miguel Ángel Garduño Córdova Isaac Méndez Hernández

Practica 1 Instalación del SGBD. Ing. María Elena Reyes Castellanos. Miguel Ángel Garduño Córdova Isaac Méndez Hernández Investigación Practica 1 Instalación del SGBD Catedrático: Alumnos: Ing. María Elena Reyes Castellanos Miguel Ángel Garduño Córdova Isaac Méndez Hernández 1 ÍNDICE DE GENERAL INDICE DE TABLAS Y FIGURAS

Más detalles

DOCENTES FORMADORES UGEL 03 PRIMARIA

DOCENTES FORMADORES UGEL 03 PRIMARIA DOCENTES FORMADORES UGEL 03 PRIMARIA 1. Recursos y Aplicaciones del Servidor La página de inicio del servidor (http://escuela) contiene los enlaces a las aplicaciones instaladas en el servidor, un enlace

Más detalles

Introducción a la Firma Electrónica en MIDAS

Introducción a la Firma Electrónica en MIDAS Introducción a la Firma Electrónica en MIDAS Firma Digital Introducción. El Módulo para la Integración de Documentos y Acceso a los Sistemas(MIDAS) emplea la firma digital como método de aseguramiento

Más detalles

MANUAL DE NAVEGACIÓN DEL SIIA-WEB versión 1.0. http://148.216.31.29:8080/siia/ PRONAD

MANUAL DE NAVEGACIÓN DEL SIIA-WEB versión 1.0. http://148.216.31.29:8080/siia/ PRONAD MANUAL DE NAVEGACIÓN DEL SIIA-WEB versión 1.0 http://148.216.31.29:8080/siia/ PRONAD II C o n t e n i d o 1 Tabla de contenido C o n t e n i d o... I 1. Bienvenido...III 2. Antes de Comenzar...III 3. Iniciando

Más detalles

Desarrollo y servicios web

Desarrollo y servicios web Desarrollo y servicios web Luisa Fernanda Rincón Pérez 2015-1 Qué vimos la clase pasada? 1. Fin tutorial HTML 2. Nombres de dominio 3. URLs 3 Sesión 4. Método GET - POST Qué haremos hoy? 1. Tipos de solicitudes

Más detalles

ALGUNAS AYUDAS PARA EL ACCESO AL AULA DIGITAL Contenido

ALGUNAS AYUDAS PARA EL ACCESO AL AULA DIGITAL Contenido ALGUNAS AYUDAS PARA EL ACCESO AL AULA DIGITAL Contenido Tabla de contenido 1 INFORMACIÓN PERSONAL... 2 1.1 Cómo ingresar al Aula Digital?... 2 1.2 Qué hacer si olvida su contraseña?... 2 1.3 Qué veo cuando

Más detalles

APÉNDICE E: MANUAL DE USUARIO PARA EL SISTEMA DE MONITOREO DE REDES LAN.

APÉNDICE E: MANUAL DE USUARIO PARA EL SISTEMA DE MONITOREO DE REDES LAN. APÉNDICE E: MANUAL DE USUARIO PARA EL SISTEMA DE MONITOREO DE REDES LAN. Objetivo: Mostrar al usuario administrador el funcionamiento del sistema, junto con los datos que debe ingresar, además de interactuar

Más detalles

UTILIZANDO EL SQUIRREL MAIL

UTILIZANDO EL SQUIRREL MAIL UTILIZANDO EL SQUIRREL MAIL En la actualidad son varios los proveedores de alojamiento, que incluyen el squirrel mail como cliente de correo electrónico, así que vamos a darle una rápida mirada para aprender

Más detalles

Accede a su DISCO Virtual del mismo modo como lo Hace a su disco duro, a través de:

Accede a su DISCO Virtual del mismo modo como lo Hace a su disco duro, a través de: Gemelo Backup Online DESKTOP Manual DISCO VIRTUAL Es un Disco que se encuentra en su PC junto a las unidades de discos locales. La información aquí existente es la misma que usted ha respaldado con su

Más detalles

Unidad IV: Servlets. Comprender la estructura básica de los Servlets Crear servlets sencillos Presentar el ciclo de vida de un Servlet.

Unidad IV: Servlets. Comprender la estructura básica de los Servlets Crear servlets sencillos Presentar el ciclo de vida de un Servlet. Unidad IV: Servlets Introducción Este unidad presenta los conceptos de Servlets Objetivos Comprender la estructura básica de los Servlets Crear servlets sencillos Presentar el ciclo de vida de un Servlet.

Más detalles

Universidad Tecnológica del Valle del Mezquital. Desarrollo de Aplicaciones Web. Manual JSP

Universidad Tecnológica del Valle del Mezquital. Desarrollo de Aplicaciones Web. Manual JSP Universidad Tecnológica del Valle del Mezquital Desarrollo de Aplicaciones Web Manual JSP Presentado por: Amellaly Perez Ramirez Ana Maday Perez Montoya Eduardo Perez Ignacio Jairo Mohedano Mejia Maricela

Más detalles

Lectura No. 3. Contextualización. Nombre: Página web DISEÑO DIGITAL 1. Para qué te sirve saber elaborar una página web?

Lectura No. 3. Contextualización. Nombre: Página web DISEÑO DIGITAL 1. Para qué te sirve saber elaborar una página web? Diseño Digital DISEÑO DIGITAL 1 Lectura No. 3 Nombre: Página web Contextualización Para qué te sirve saber elaborar una página web? A través de una página web puedes atraer a una mayor cantidad de clientes

Más detalles

Tema 4: Tecnologías Web Java

Tema 4: Tecnologías Web Java Tema 4: Tecnologías Web Java Introducción Aplicación web Aplicación que corre en al menos un servidor y a la que el usuario accede desde un cliente de propósito general (ej.: navegador en un PC, teléfono

Más detalles

MANUAL PARA GESTIÓN DE INCIDENCIAS INFORMÁTICAS

MANUAL PARA GESTIÓN DE INCIDENCIAS INFORMÁTICAS MANUAL PARA GESTIÓN DE INCIDENCIAS INFORMÁTICAS En este manual aprenderemos a introducir un Ticket de Soporte (Incidencia Informática) y ver todo el proceso hasta que se resuelve. Para poder escribir Tickets

Más detalles

ENVÍO DE E-MAIL POR MEDIO DE SMTP

ENVÍO DE E-MAIL POR MEDIO DE SMTP UNIVERSIDAD TÉCNICA FEDERICO SANTA MARÍA DEPARTAMENTO DE ELECTRÓNICA ELO 322: REDES DE COMPUTADORES I ENVÍO DE E-MAIL POR MEDIO DE SMTP Alumnos Ariel Mancilla G. 2521040-9 Daniel Spataris J. 2521029-8

Más detalles

Introducción a las Redes de Computadoras. Obligatorio 2 2011

Introducción a las Redes de Computadoras. Obligatorio 2 2011 Introducción a las Redes de Computadoras Obligatorio 2 2011 Facultad de Ingeniería Instituto de Computación Departamento de Arquitectura de Sistemas Nota previa - IMPORTANTE Se debe cumplir íntegramente

Más detalles

REDES DE ÁREA LOCAL. APLICACIONES Y SERVICIOS EN WINDOWS

REDES DE ÁREA LOCAL. APLICACIONES Y SERVICIOS EN WINDOWS REDES DE ÁREA LOCAL. APLICACIONES Y SERVICIOS EN WINDOWS Servicio DNS - 1 - Servicio DNS...- 3 - Definición... - 3 - Instalación... - 5 - Configuración del Servidor DNS...- 10 - - 2 - Servicio DNS Definición

Más detalles

PRÁCTICA 10. Configuración de Correo y Publicar en la Web

PRÁCTICA 10. Configuración de Correo y Publicar en la Web PRÁCTICA 10. Configuración de Correo y Publicar en la Web INFORMÁTICA BÁSICA Publicidad y Relaciones Públicas y Periodismo. Curso 2006/2007 1. Configuración del correo Gestores de correo en la máquina

Más detalles

Sección de Introducción.

Sección de Introducción. Sección de Introducción. Imagen 1: Nueva pantalla de bienvenida. La primer pantalla que los usuarios visualizarán, en la última versión del software, es la sección de Introducción. Aquí los usuarios pueden

Más detalles

Unidad II. - Las técnicas en las que se basó, las categorías de análisis o ejes centrales que permiten guiar el proceso de investigación.

Unidad II. - Las técnicas en las que se basó, las categorías de análisis o ejes centrales que permiten guiar el proceso de investigación. Unidad II Metodología de Solución de Problemas 2.1 Descripción del problema (enunciado). Este aspecto nos indica describir de manera objetiva la realidad del problema que se esta investigando. En la descripción

Más detalles

CREAR UN SERVICIO WEB BASICO CON JAVA AXIS2. Víctor J. Sosa vjsosa@tamps.cinvestav.mx

CREAR UN SERVICIO WEB BASICO CON JAVA AXIS2. Víctor J. Sosa vjsosa@tamps.cinvestav.mx CREAR UN SERVICIO WEB BASICO CON JAVA AXIS2. Víctor J. Sosa vjsosa@tamps.cinvestav.mx En este documento explicaré brevemente cómo construir un servicio web con Java Axis2 y cómo invocarlo desde un cliente

Más detalles

GUÍA Nro. 1 TECNOLOGÍA DE INTERNET. TIII PIII

GUÍA Nro. 1 TECNOLOGÍA DE INTERNET. TIII PIII GUÍA Nro. 1 TECNOLOGÍA DE INTERNET. TIII PIII GUIA DISPONIBLE EN: http://preparadorivan.blogspot.com/ - http://preparadormssi.50webs.com/inicio.html La World Wide Web o la Web, es una de las múltiples

Más detalles

Agosto. Un primer JSP. Guía rápida. [ h t t p : / / w w w. o p e n b o x e r. 2 6 0 m b. c o m / j a v a. p h p ]

Agosto. Un primer JSP. Guía rápida. [ h t t p : / / w w w. o p e n b o x e r. 2 6 0 m b. c o m / j a v a. p h p ] Agosto 09 Un primer JSP Guía rápida [ h t t p : / / w w w. o p e n b o x e r. 2 6 0 m b. c o m / j a v a. p h p ] Un Primer JSP Guía rápida Este documento te guiará por los primeros pasos para desarrollar

Más detalles

Introducción a los servlets

Introducción a los servlets Introducción a los servlets (Febrero de 2005) Introducción En breve: un servlet es un programa ejecutado en el servidor (a diferencia de los applets que se ejecutan en el cliente). Es un mecanismo para

Más detalles

Manual de iniciación a

Manual de iniciación a DOCUMENTACIÓN Picasa y otras nubes Manual de iniciación a DROPBOX 1 Últimamente se ha hablado mucho de la nube y de cómo es el futuro de la Web. También se han presentado servicios y aplicaciones que ya

Más detalles

Para poder navegar en Internet debes primeramente elegir el navegador que vas a utilizar, que puede ser:

Para poder navegar en Internet debes primeramente elegir el navegador que vas a utilizar, que puede ser: Módulo 2 Herramientas para la búsqueda virtual en Internet Navegadores Web Para establecer conexiones con los servidores electrónicos y obtener la información y los servicios que éstos prestan, el usuario

Más detalles

Modulo I. Introducción a la Programación Web. 1.1 Servidor Web.

Modulo I. Introducción a la Programación Web. 1.1 Servidor Web. Modulo I. Introducción a la Programación Web. 1.1 Servidor Web. Antes de analizar lo que es un servidor Web y llevara a cabo su instalación, es muy importante identificar diferentes elementos involucrados

Más detalles

MANUAL BASICO DE WEBEX

MANUAL BASICO DE WEBEX MANUAL BASICO DE WEBEX Webex es un servicio de web conferencias y soluciones de colaboración, lo que significa que nos permite crear una conferencia por internet en la cual además de vernos los unos a

Más detalles

Reglas de Uso del PACE

Reglas de Uso del PACE (PACE) Reglas de Uso del PACE Dirección de Operación y Financiamiento Dirección General de Bachillerato SUBSECRETARÍA DE EDUCACIÓN MEDIA SUPERIOR 1 CONTENIDO Introducción... 3 Requisitos para operar el

Más detalles

GLOSARIO. Arquitectura: Funcionamiento, estructura y diseño de una plataforma de desarrollo.

GLOSARIO. Arquitectura: Funcionamiento, estructura y diseño de una plataforma de desarrollo. GLOSARIO Actor: Un actor es un usuario del sistema. Esto incluye usuarios humanos y otros sistemas computacionales. Un actor usa un Caso de Uso para ejecutar una porción de trabajo de valor para el negocio.

Más detalles

CONFEDERACIÓN DE EMPRESARIOS DE MÁLAGA

CONFEDERACIÓN DE EMPRESARIOS DE MÁLAGA GUÍA DEL ALUMNO 1 Introducción 2 Acceso a la plataforma 3 Cerrar sesión 4 Estructura del curso virtual 5 Foros 5.1 No quiero recibir copias de los foros en mi email 6 Mensajería Interna 7 Como subir tareas

Más detalles

HTTP, CGI, Applets y Servlets

HTTP, CGI, Applets y Servlets HTTP, CGI, Applets y Servlets Sistemas de Operación II CI-4821 Sep-Dic 2006 Mercedes Martínez 00-33042 Aixbel Martínez 01-34114 Mario Felaco 02-34888 José Luís Castillo 01-33691 Yonathan Ledo 01-34033

Más detalles

Sistemas de Información 12/13 Servlets y JSPs (Java Server Pages)

Sistemas de Información 12/13 Servlets y JSPs (Java Server Pages) 12/13 Servlets y JSPs (Java Server Pages) Departamento Informática e Ingeniería de Sistemas Universidad de Zaragoza (raqueltl@unizar.es) " Guión Introducción Servlets Introducción Clases e interfaces del

Más detalles

CONFIGURACION AVANZADA DE OUTLOOK EXPRESS 6

CONFIGURACION AVANZADA DE OUTLOOK EXPRESS 6 CONFIGURACION AVANZADA DE OUTLOOK EXPRESS 6 Carpetas sin conexión Gestión de mensajes enviados Gestión de mensajes eliminados Firma digital Envío de mensajes firmados digitalmente Recepción de mensajes

Más detalles

Manual de Instalación y uso de FTP

Manual de Instalación y uso de FTP Manual de Instalación y uso de FTP Que es el FTP? El FTP es un sistema que nos permite de forma cómoda subir o bajar archivos a otra ubicación. Hay FTP públicos y privados, es decir en algunos todo el

Más detalles

Práctica 3: Estudio de los protocolos HTTP, SMTP, POP3 e IMAP mediante un analizador de red: Wireshark

Práctica 3: Estudio de los protocolos HTTP, SMTP, POP3 e IMAP mediante un analizador de red: Wireshark FUNDAMENTOS DE REDES DE COMPUTADORES Curso 2009/2010 Práctica 3: Estudio de los protocolos HTTP, SMTP, POP3 e IMAP mediante un analizador de red: Wireshark Introducción En esta práctica vamos a trabajar

Más detalles

Tutorial Servicios Web

Tutorial Servicios Web Tutorial Servicios Web 1. Servicios Web con REST Como ya hemos usado SOAP para WebService, podemos afirmar que es bien fácil de diseñar, pero algo complicado de consumir: se necesita toda una API para

Más detalles

Clase. geniería de la Computación. Departamento de Ciencias e Ing. Diego C. Martínez - DCIC-UNS

Clase. geniería de la Computación. Departamento de Ciencias e Ing. Diego C. Martínez - DCIC-UNS Tecnología de Programación Clase 22 Diego C. Martínez Departamento de Ciencias e Ing geniería de la Computación Universidad Nacional del Sur Componentes Web J2EE presenta los componentes Web (web components):

Más detalles

ÍTEMS DEL MENÚ CREACIÓN Y GESTIÓN (Última revisión: lunes, 9 de marzo de 2009)

ÍTEMS DEL MENÚ CREACIÓN Y GESTIÓN (Última revisión: lunes, 9 de marzo de 2009) JOOMLA! ÍTEMS DEL MENÚ CREACIÓN Y GESTIÓN (Última revisión: lunes, 9 de marzo de 2009) Es necesario comentar que este manual ha sido diseñado en su mayor parte por comunidadjoomla.org. Este manual es una

Más detalles

Escudo Movistar Guía Rápida de Instalación Dispositivos Symbian

Escudo Movistar Guía Rápida de Instalación Dispositivos Symbian Escudo Movistar Guía Rápida de Instalación Dispositivos Symbian Guía de Instalación Página 1 Índice ESCUDO MOVISTAR.... 3 1. INSTALACIÓN DEL SERVICIO ESCUDO MOVISTAR... 3 1.1. VERSIONES SOPORTADAS... 3

Más detalles

DOCUMENTOS COMPARTIDOS CON GOOGLE DOCS

DOCUMENTOS COMPARTIDOS CON GOOGLE DOCS DOCUMENTOS COMPARTIDOS CON GOOGLE DOCS 1. Introducción Los ambientes de aprendizaje acompañados de trabajos colaborativos como estrategia se revierten en actividades de diferente índole (análisis de videos,

Más detalles

Capítulo VI. Conclusiones. En este capítulo abordaremos la comparación de las características principales y

Capítulo VI. Conclusiones. En este capítulo abordaremos la comparación de las características principales y Capítulo VI Conclusiones En este capítulo abordaremos la comparación de las características principales y de las ventajas cada tecnología Web nos ofrece para el desarrollo de ciertas aplicaciones. También

Más detalles

PROGRAMA PARA LA RECEPCIÓN VALIDACIÓN Y RESGUARDO DE DOCUMENTOS FISCALES VERSIÓN 1.00 MANUAL DE OPERACIÓN

PROGRAMA PARA LA RECEPCIÓN VALIDACIÓN Y RESGUARDO DE DOCUMENTOS FISCALES VERSIÓN 1.00 MANUAL DE OPERACIÓN PROGRAMA PARA LA RECEPCIÓN VALIDACIÓN Y RESGUARDO DE DOCUMENTOS FISCALES VERSIÓN 1.00 MANUAL DE OPERACIÓN ENERO 2014 Versión 1.00 Página 1 de 12 CONTENIDO 1.- Introducción 2.- Entrar y Salir del Programa

Más detalles

Preguntas más frecuentes

Preguntas más frecuentes Preguntas más frecuentes Usuario... 2 Cómo se accede al Aula Virtual?... 2 Usuario sin acceso a la plataforma... 3 No tengo disponible en la plataforma el curso en el que me he matriculado... 3 He olvidado

Más detalles

Manual de NetBeans y XAMPP

Manual de NetBeans y XAMPP Three Headed Monkey Manual de NetBeans y XAMPP Versión 1.0 Guillermo Montoro Delgado Raúl Nadal Burgos Juan María Ruiz Tinas Lunes, 22 de marzo de 2010 Contenido NetBeans... 2 Qué es NetBeans?... 2 Instalación

Más detalles

3. Qué necesitamos para usar Wordpress?

3. Qué necesitamos para usar Wordpress? Contenido 1. Objetivos de este tutorial... 2 2. Qué es Wordpress?... 2 3. Qué necesitamos para usar Wordpress?... 2 3.1 Alojamiento web... 3 3.2 DOMINIO O DIRECCIÓN DE INTERNET... 3 3.3 Cuenta FTP... 4

Más detalles

1. Solicitando una cuenta de correo a nuestro proveedor de Internet. 2. Adquiriendo una cuenta de correo a través de la web (webmail).

1. Solicitando una cuenta de correo a nuestro proveedor de Internet. 2. Adquiriendo una cuenta de correo a través de la web (webmail). CORREO ELECTRÓNICO NIVEL BÁSICO DE CORREO ELECTRÓNICO INICIACIÓN A CORREO ELECTRÓNICO OBTENER UNA CUENTA DE CORREO ELECTRÓNICO GRATUITA Al correo electrónico también se lo conoce como e-mail, abreviatura

Más detalles

Capitulo VI. Conclusiones.

Capitulo VI. Conclusiones. Capitulo VI. Conclusiones. VI.I. Conclusiones. Finalmente como conclusiones tenemos que resaltar el uso de varias tecnologías aparte de Java, como lo son el uso de la librería O reilly para pasar archivos

Más detalles

Sitios remotos. Configurar un Sitio Remoto

Sitios remotos. Configurar un Sitio Remoto Sitios remotos Definir un sitio remoto significa establecer una configuración de modo que Dreamweaver sea capaz de comunicarse directamente con un servidor en Internet (por eso se llama remoto) y así poder

Más detalles

Internet como herramientas de comunicación: El correo electrónico

Internet como herramientas de comunicación: El correo electrónico Internet como herramientas de comunicación: El correo electrónico 1. El correo electrónico Objetivo del tema: Aprender a manejar el correo electrónico y los medios de comunicación existentes en Internet.

Más detalles

Crear un servidor Web en IIS

Crear un servidor Web en IIS Crear un servidor Web en IIS Qué es un servidor web? Un servidor web es un programa que se ejecuta continuamente en un computador, manteniéndose a la espera de peticiones de ejecución que le hará un cliente

Más detalles

Como Construir Una Lista De Prospectos En 30 días (O Menos)

Como Construir Una Lista De Prospectos En 30 días (O Menos) Como Construir Una Lista De Prospectos En 30 días (O Menos) Autor: Carlos Hernandez 1 Descargo de Responsabilidad Este curso es sólo para fines informativos y el autor no acepta responsabilidad alguna

Más detalles

Ayuda para la instalación Componente Firma Digital INDICE. 1 Configuración previa...2. 1.1 Configuración Internet Explorer para ActiveX...

Ayuda para la instalación Componente Firma Digital INDICE. 1 Configuración previa...2. 1.1 Configuración Internet Explorer para ActiveX... INDICE 1 Configuración previa...2 1.1 Configuración Internet Explorer para ActiveX...2 1.2 Problemas comunes en sistema operativo Windows...8 1.2.1 Usuarios con sistema operativo Windows XP con el Service

Más detalles

El Internet tuvo origen en los Estados Unidos de Norte América cuando en un proyecto

El Internet tuvo origen en los Estados Unidos de Norte América cuando en un proyecto 2 Marco teórico 2.1 Internet 2.1.1 Breve historia El Internet tuvo origen en los Estados Unidos de Norte América cuando en un proyecto realizado por la Agencia de Investigación Avanzados de Defensa (DARPA)

Más detalles

Guía de Apoyo Project Web Access. (Jefe de Proyectos)

Guía de Apoyo Project Web Access. (Jefe de Proyectos) Guía de Apoyo Project Web Access (Jefe de Proyectos) 1 ÍNDICE Contenido INTRODUCCIÓN... 3 CAPITULO I: ELEMENTOS INICIALES DE PROJECT WEB ACCESS... 4 Configuración General... 4 Área de Trabajo del Proyecto...

Más detalles

Procedimiento para realizar la configuración de Internet Explorer y usar el Sistema de reservaciones Go! Res versión 4.x

Procedimiento para realizar la configuración de Internet Explorer y usar el Sistema de reservaciones Go! Res versión 4.x Procedimiento para realizar la configuración de Internet Explorer y usar el Sistema de reservaciones Go! Res versión 4.x Ayuda en línea: http://globallearningcenter.wspan.com/méxico/pdfs/documentation/configuración%20internet%2

Más detalles

Unidad I. 1.1 Sistemas numéricos (Binario, Octal, Decimal, Hexadecimal)

Unidad I. 1.1 Sistemas numéricos (Binario, Octal, Decimal, Hexadecimal) Unidad I Sistemas numéricos 1.1 Sistemas numéricos (Binario, Octal, Decimal, Hexadecimal) Los computadores manipulan y almacenan los datos usando interruptores electrónicos que están ENCENDIDOS o APAGADOS.

Más detalles

3. Número inicial y número final de mensajes mostrados en la página actual.

3. Número inicial y número final de mensajes mostrados en la página actual. Sistema WEBmail El sistema WEBmail permite el acceso rápido y sencillo a su buzón de correo utilizando un navegador de páginas Web. Normalmente es usado como complemento al lector de correo tradicional,

Más detalles

Guía para publicar su equipo en Internet.

Guía para publicar su equipo en Internet. Antes de comenzar Guía para publicar su equipo en Internet. Para configurar su equipo y poder publicar sus cámaras en Internet, primeramente es necesario haber abierto los puertos de video y web, que por

Más detalles

Clase Java que implementa un modelo de programación peticiónrespuesta. Puede usarse para procesar cualquier tipo de petición

Clase Java que implementa un modelo de programación peticiónrespuesta. Puede usarse para procesar cualquier tipo de petición Java EE Servlets Aplicaciones Web/Sistemas Web Juan Pavón Mestras Dep. Ingeniería del Software e Inteligencia Artificial Facultad de Informática Universidad Complutense Madrid Material bajo licencia Creative

Más detalles

Curso de Spring Framework

Curso de Spring Framework Todos los Derechos Reservados Global Mentoring 2012 Experiencia y Conocimiento para tu Vida 1 Spring es un proyecto de código abierto (open source), originalmente creado por Rod Johnson y descrito en su

Más detalles

TERMINOS DE USO DE LOS SITIOS WEB PROPIEDAD DE COMERCIALIZADORA SIETE S.A. DE C.V

TERMINOS DE USO DE LOS SITIOS WEB PROPIEDAD DE COMERCIALIZADORA SIETE S.A. DE C.V TERMINOS DE USO DE LOS SITIOS WEB PROPIEDAD DE COMERCIALIZADORA SIETE S.A. DE C.V El sitio web www.gruposiete.com.mx es propiedad de Comercializadora Siete S.A de C.V. Este sitio como todos aquellos que

Más detalles

MANUAL DE USUARIOS DEL SISTEMA MESA DE SOPORTE PARA SOLICITAR SERVICIOS A GERENCIA DE INFORMATICA

MANUAL DE USUARIOS DEL SISTEMA MESA DE SOPORTE PARA SOLICITAR SERVICIOS A GERENCIA DE INFORMATICA MANUAL DE USUARIOS DEL SISTEMA MESA DE SOPORTE PARA SOLICITAR SERVICIOS A Usuario Propietario: Gerencia de Informática Usuario Cliente: Todos los usuarios de ANDA Elaborada por: Gerencia de Informática,

Más detalles

TUTORIAL PRÁCTICO COMPLETO DE BASE DE DATOS EN PHPMYADMIN Y GESTIÓN DESDE DREAMWEAVER

TUTORIAL PRÁCTICO COMPLETO DE BASE DE DATOS EN PHPMYADMIN Y GESTIÓN DESDE DREAMWEAVER TUTORIAL PRÁCTICO COMPLETO DE BASE DE DATOS EN PHPMYADMIN Y GESTIÓN DESDE DREAMWEAVER 1. Crear una nueva base de datos en phpmyadmin Abrimos el wampserver y luego el phpmyadmin Para seguir este tutorial,

Más detalles

Laboratorio de Redes y Sistemas Operativos Trabajo Práctico Final

Laboratorio de Redes y Sistemas Operativos Trabajo Práctico Final Laboratorio de Redes y Sistemas Operativos Trabajo Práctico Final Tema: Instalación de X2GO Profesor: Di Biase José Luis Integrantes: Cardozo Griselda Chiniewicz Stefania Arnez Inochea Eric 1 Índice: 1.

Más detalles

Sesión No. 4. Contextualización INFORMÁTICA 1. Nombre: Procesador de Texto

Sesión No. 4. Contextualización INFORMÁTICA 1. Nombre: Procesador de Texto INFORMÁTICA INFORMÁTICA 1 Sesión No. 4 Nombre: Procesador de Texto Contextualización La semana anterior revisamos los comandos que ofrece Word para el formato del texto, la configuración de la página,

Más detalles

Diplomado Java Web Programming with Servlets, JSP, JSF & Ajax

Diplomado Java Web Programming with Servlets, JSP, JSF & Ajax Diplomado Java Web Programming with Servlets, JSP, JSF & Ajax Descripción: Por nuestra experiencia de más de 11 años enseñando Java y pioneros en este tipo de Diplomados creamos este entrenamiento. Nuestro

Más detalles

Redes de área local: Aplicaciones y servicios WINDOWS

Redes de área local: Aplicaciones y servicios WINDOWS Redes de área local: Aplicaciones y servicios WINDOWS 4. Servidor DNS 1 Índice Definición de Servidor DNS... 3 Instalación del Servidor DNS... 5 Configuración del Servidor DNS... 8 2 Definición de Servidor

Más detalles

La página web del centro con SPIP

La página web del centro con SPIP La página web del centro con SPIP Ponente: Daniel López Avellaneda 8 - Práctica en Internet Manual para el curso organizado por: CEP provincia de Córdoba http://cibermatex.com/?page=suscripciones 28 Enero

Más detalles