tomilloonce.files.wordpress.com  · web view-tema 4. ser un servlet-los servlets viven al servicio...

21
-Tema 4. Ser un Servlet -Los servlets viven al servicio del cliente. Su trabajo es coger la petición del cliente (request) y mandarle una respuesta de vuelta (response). -Los servlets son controlados por el Container. Pasos: 1. El usuario hace clic en un enlace que tiene una URL a un servlet. 2. El Contenedor "ve" que la solicitud es para un servlet, por lo que el contenedor crea dos objetos: - HttpServletResponse - HttpServletRequest 3. El contenedor encuentra el servlet correcto basado en la URL en el solicitud, crea o asigna un hilo para esa petición, y llama a los métodos del servlet (), pasando los objetos petición y respuesta como argumentos. 4. Dependiendo de cómo se envie la solicitud podrá ir por get/post. 5. El servlet usa la respuesta del objeto para escribir la respuesta para el cliente. La respuesta va a través del container. 6. Cuando se completa los métodos del service, el hilo se muere. Los objetos request y response ya pueden ser leidos por el garbage collection. El cliente recibe la respuesta. - El ciclo de vida de un servlet. - Sólo hay un estado principal: Inicializado.

Upload: others

Post on 02-Oct-2020

5 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: tomilloonce.files.wordpress.com  · Web view-Tema 4. Ser un Servlet-Los servlets viven al servicio del cliente. Su trabajo es coger la petición del cliente (request) y mandarle

-Tema 4. Ser un Servlet-Los servlets viven al servicio del cliente. Su trabajo es coger la petición del cliente (request) y mandarle una respuesta de vuelta (response).-Los servlets son controlados por el Container. Pasos:

1. El usuario hace clic en un enlace que tiene una URL a un servlet.

2. El Contenedor "ve" que la solicitud es para un servlet, por lo que el contenedor crea dos objetos:

- HttpServletResponse- HttpServletRequest3. El contenedor encuentra el servlet correcto basado en la URL en el solicitud, crea o asigna un hilo para esa petición, y llama a los métodos del servlet (), pasando los objetos petición y respuesta como argumentos.4. Dependiendo de cómo se envie la solicitud podrá ir por

get/post.5. El servlet usa la respuesta del objeto para escribir la respuesta para el cliente. La respuesta va a través del container.6. Cuando se completa los métodos del service, el hilo se muere. Los objetos request y response ya pueden ser leidos por el garbage collection. El cliente recibe la respuesta.

- El ciclo de vida de un servlet.- Sólo hay un estado principal: Inicializado.- Si el servlet no está inicializado, puede que se esté

inicializando ( ejecutándose el constructor o el método init), o está siendo destruido (método destroy() o no existe.Ciclo de vida.

1. init().El container llama al método init() después de crear la instancia del servlet pero antes de que el servlet pueda dar servicio a las peticiones de los clientes.

Page 2: tomilloonce.files.wordpress.com  · Web view-Tema 4. Ser un Servlet-Los servlets viven al servicio del cliente. Su trabajo es coger la petición del cliente (request) y mandarle

Se puede iniciar el servlet antes de manipular cualquier petición del cliente.Si tenemos ya un código de inicialización, hay que sobrescribir el método init () en la clase servlet.

2. Service () Cuando la primera solicitud de un cliente entra, el Container empieza un nuevo hilo o asigna un hilo de la piscina y el método service del servlet será invocado.Este método analiza la request, determina el método HTTP (get, post,) e invoca a los métodos doGet, doPost en el servlet. No se debe de sobrescribir el método service(). Siempre es llamado desde su propio stack.Se sobrescribe el doGet o doPost.

3. doGet/doPostEl método de servicio () invoca doGet () o doPost () basado en el método HTTP (GET, POST, etc) a partir del request.Estos son los métodos responsables de que la app funcione, es decir, lo que deben de hacer. Estos métodos hay que sobrescribirlo aunque sea uno de ellos.

Cada request se ejecuta en un hilo distintoEl container ejecuta multiple hilos para procesar multiples request en un solo servlet.

Init() always completes before the first call to serviceInit() solo se ejecuta una vez durante la vida del servlet asi que ten mucho cuidado.

Page 3: tomilloonce.files.wordpress.com  · Web view-Tema 4. Ser un Servlet-Los servlets viven al servicio del cliente. Su trabajo es coger la petición del cliente (request) y mandarle

Con el constructor sólo se crea un objeto no un servlet.

A ServletConfig objectUn ServletConfig por servlet.Inicializar parametros del servlet.Se usa para acceder al ServletContext.Parametros configurados en el web.xml.A ServletContext Un ServletContext por web app.Usa para acceder a parámetros de la web app también configurados en el web.xml

Métodos HTTP GET: Se utiliza para obtener recursos activos o pasivos,

generalmente  para archivos HTML o imágenes. POST: Se utiliza generalmente para enviar grandes cantidades

de información, subir archivos binarios, o para enviar nombres de usuarios y contraseñas para que no sean vistas como partes de una URL. La información se envía en el cuerpo de la petición.

Page 4: tomilloonce.files.wordpress.com  · Web view-Tema 4. Ser un Servlet-Los servlets viven al servicio del cliente. Su trabajo es coger la petición del cliente (request) y mandarle

HEAD: Es similar al método GET, salvo que solo devuelve los encabezados de respuesta y no devuelve ningún mensaje en el cuerpo. Se utiliza generalmente para determinar el estado de un recurso y verificar la fecha de última modificación.

TRACE: Se utiliza para ver cuáles son los datos que se están enviando al servidor. De esta manera el cliente puede ver que es lo que envía al otro lado, es útil para realizar pruebas y para la resolución de casos.

PUT: Se utiliza para guardar la información adjuntada en el cuerpo de la petición (similar a POST).

DELETE: Se utiliza para indicar que se debe eliminar el recurso especificado con la URL.

OPTIONS: Permite obtener una lista de los métodos HTTP, los cuales se pueden utilizar para responder a cierto recurso.

CONNECT: Se utiliza para propósitos de tunneling (enrutamientos).

Manejando peticiones HTTP en un HttpServletPara cada método HTTP, existe un correspondiente método en la clase HttpServlet que tiene la signatura (donde doXXX depende del método HTTP):protected void doXXX (HttpServletRequest, HttpServletResponse) throws ServletException, IOException;

GET: doGet() POST: doPost() HEAD: doHead() TRACE: doTrace() PUT: doPut() DELETE: doDelete() OPTIONS: doOptions()

Flujo de control del contenedor de servlets:1. El contenedor de servlets invoca el método de HttpServlet:

service (ServletRequest, ServletResponse).

Page 5: tomilloonce.files.wordpress.com  · Web view-Tema 4. Ser un Servlet-Los servlets viven al servicio del cliente. Su trabajo es coger la petición del cliente (request) y mandarle

2. El método anterior invoca al método (sobrecargado en la misma clase): service (HttpServletRequest, HttpServletResponse).

3. El método anterior analiza la petición y dependiendo del método HTTP utilizado invoca el correspondiente método doXXX() del servlet.

Es aconsejable no sobrescribir el método service(), debido a que se pierde la funcionalidad  de la clase HttpServlet. Se recomienda solo sobrescribir los métodos doGet() y doPost().Muchos de los componentes más importantes de la API de Servlets, incluyen las interfaces HttpServletRequest y HttpServletResponse. Es el contenedor de servlets el que provee las clases que implementan dichas interfaces.En caso de que se intente realizar una petición a un servlet, el cual no haya sobrescrito el método correspondiente (doGet() o doPost()) se devolverá un error 405 indicando dicha problemática. Es decir, si un servlet solo posee el método doGet(), al mismo solo se podrá acceder a través de este método HTTP y no otro (si se intenta se obtendrá el error 405).

Analizando las peticiones (javax.servlet.ServletRequest y javax.servlet.HttpServletRequest)Las interfaces ServletRequest y HttpServletRequest permiten analizar una petición. Proveen una vista de la información enviada desde el navegador. La interface ServletRequest provee métodos relevantes para cualquier protocolo, mientras que HttpServletRequest agrega otros específicos para el protocolo HTTP.

Page 6: tomilloonce.files.wordpress.com  · Web view-Tema 4. Ser un Servlet-Los servlets viven al servicio del cliente. Su trabajo es coger la petición del cliente (request) y mandarle

Métodos pertenecientes a la interface ServletRequest para obtener los parámetros enviados por un cliente:

String getParameter (String paramName): Devuelve el valor asociado al parámetro.

String[] getParameterValues (String paramName): Devuelve un arreglo de todos los valores asociados a un parámetro.

Enumeration getParameterNames (): Devuelve un objeto Enumeration con todos los nombres de los parámetros.

Métodos de HttpServletRequest para obtener los encabezados de un request (los headers son específicos del protocolo http):

String getHeader (String headerName): Devuelve el valor asociado al encabezado.

Enumeration getHeaders (String headerName): Devuelve un objeto Enumeration con todos los valores asociados a un encabezado.

Enumeration getHeadersNames (): Devuelve un objeto Enumeration con todos los nombres de los encabezados.

Enviando las respuestas (javax.servlet.ServletResponse y javax.servlet.http.HttpServletResponse)

Page 7: tomilloonce.files.wordpress.com  · Web view-Tema 4. Ser un Servlet-Los servlets viven al servicio del cliente. Su trabajo es coger la petición del cliente (request) y mandarle

La interface ServletResponse provee métodos relevantes para cualquier protocolo, mientras que HttpServletResponse agrega otros específicos para el protocolo HTTP. Una instancia de HttpServletResponse funciona como la vía para que el servlet envíe información de vuelta al navegador.

Métodos de la interface ServletResponse: PrintWriter getWriter (): Devuelve un objeto java.io.PrintWriter

el cuál puede ser utilizado para enviar caracteres al cliente. Este objeto se utiliza extensivamente en los servlets para generar páginas dinámicas HTML.

ServletOutputStream getOutputStream (): Devuelve un objeto javax.servlet.ServletOutputStream el cual permite enviar archivos binarios al cliente. Dicho objeto hereda de java.io.OutputStream.

void setContentType (String type): Permite especificar el tipo MIME de la información que se devuelve en la respuesta de una petición. También se puede incluir la codificación de caracteres utilizada en la respuesta. Este método se debe invocar antes del método getWriter(), para así obtener un objeto PrintWriter con esta información seteada.

Page 8: tomilloonce.files.wordpress.com  · Web view-Tema 4. Ser un Servlet-Los servlets viven al servicio del cliente. Su trabajo es coger la petición del cliente (request) y mandarle

Solo uno de los métodos getWriter() y getOutputStream() puede ser invocado en una instancia de un objeto ServletResponse. En caso contrario, la invocación al segundo método lanzará la excepción IllegalStateException.

Existen cuatro capacidades importantes de la interface HttpServletResponse:- Setear encabezados de respuesta: Posee siete métodos para llevar a cabo esta funcionalidad:

void setHeader (String name, String value) void setIntHeader (String name, int value) void setDateHeader (String name, long milisec) void addHeader (String name, String value) void addIntHeader (String name, int value) void addDateHeader (String name, long milisec) boolean containsHeader (String name)

- Redireccionamiento de peticiones: El método HttpServletResponse.sendRedirect (String location). Este método no puede ser invocado si la respuesta ya ha sido enviada al cliente, si se

Page 9: tomilloonce.files.wordpress.com  · Web view-Tema 4. Ser un Servlet-Los servlets viven al servicio del cliente. Su trabajo es coger la petición del cliente (request) y mandarle

invoca se lanzará la excepción IllegalStateException. El método sendRedirect() no es transparente al navegador, el servlet envía un mensaje al navegador para que este obtenga el recurso en otra parte.- Setear cookies: El método HttpServletResponse.addCookie (Cookie cookie), permite agregar cookies a la respuesta del servlet.- Enviar códigos de estado en la respuesta: El protocolo HTTP define códigos de estado para las condiciones de error comunes. Todos los códigos están definidos como constantes en la interface HttpServletResponse. Esta interface también provee los métodos sendError (int status_code) y sendError (int status_code, String msg) los cuales envían un código de estado al cliente.

Ciclo de vida de un ServletAntes de que un servlet pueda dar servicio a los clientes, el contenedor de servlets debe realizar ciertos pasos:

1.    Carga e instanciación de un servlet: Cuando se inicia el contenedor de servlets, este revisa todos los archivos de configuración de todas las aplicaciones web que aloja. Cada aplicación web posee un web.xml el cual tiene una entrada por cada servlet que utiliza. El contenedor de servlets carga cada servlet a través de la instrucción: Class.forName(className).newInstance(). Es por esto que cada servlet debe tener un constructor público sin argumentos. En caso contrario, se lanza la excepción java.lang.InstantiationException envuelta dentro de una javax.servlet.ServletException.2.    Inicialización de un servlet: Como los servlets se instancian a partir de un constructor sin argumentos (generalmente el por defecto), se utiliza el método init(ServletConfig) para realizar la

Page 10: tomilloonce.files.wordpress.com  · Web view-Tema 4. Ser un Servlet-Los servlets viven al servicio del cliente. Su trabajo es coger la petición del cliente (request) y mandarle

inicialización de los datos del servlet. El contenedor de servlets luego de instanciar el servlet, invoca este método pasando como argumento un objeto ServletConfig. Dicho objeto contiene todos los parámetros de inicialización especificados en el xml de configuración (web.xml).

La clase javax.servlet.GenericServlet posee dos métodos init(): uno con un parámetro de tipo ServletConfig y otro sin parámetros. El método init(ServletConfig) se encarga de guardar el objeto ServletConfig en el servlet e invoca el método init(). El método init() se puede sobrescribir libremente para realizar una inicialización específica. Si se sobrescribe el método init(ServletConfig) se debe incluir la invocación al método super.init(ServletConfig) para no perder  la referencia al objeto ServletConfig (la cual se obtiene a través del método getServletConfig()).

Generalmente el contenedor de servlets inicializa un servlet cuando recibe la primera petición. Si la inicialización realiza muchas tareas, el tiempo de respuesta del primer cliente va a ser muy malo. En los casos en donde esto es inaceptable, el archivo de configuración web.xml tiene la etiqueta , la cual especifica al contenedor de servlets que debe cargar e inicializar uno o más servlets automáticamente cuando el mismo se inicia. Estos dos tipos de carga e inicialización se denominan: carga perezosa (lazy loading) y precarga o preinicialización.3.    Dando servicio a las peticiones: Cuando el contenedor de servlets recibe una petición, despacha la misma a una instancia de un servlet invocando el método Servlet.service(ServletRequest, ServletResponse).4.    Destruyendo un servlet: Cuando el contenedor de servlets decide que un servlet ya no es necesario, él invoca el método destroy() sobre la instancia del servlet. Dicho método libera los recursos, y una vez que es invocado el servlet se encuentra fuera de

Page 11: tomilloonce.files.wordpress.com  · Web view-Tema 4. Ser un Servlet-Los servlets viven al servicio del cliente. Su trabajo es coger la petición del cliente (request) y mandarle

servicio (el contenedor no puede volver a ejecutar el método service()). Antes de invocar este método, el contenedor de servlets espera a que se finalice la ejecución, por parte de todos los hilos en ejecución, del método service().

Causas por las que el contenedor de servlets puede invocar el método destroy() sobre un servlet:

Si el servlet está funcionando lento sobre los recursos o ninguna petición ha llegado al servlet por un largo tiempo.

Si el contenedor de servlets mantiene un pool de instancias de servlets, puede crear y destruir las instancias.

Si el contenedor de servlets detiene sus servicios, es decir, si es apagado.

5.    Descargando un servlet: Una vez destruida, la instancia del servlet puede ser eliminada por el garbage collector, en este caso se dice que el servlet ha sido descargado.

javax.servlet.ServletConfigEsta interface provee métodos solo para obtener los parámetros del archivo de configuración web.xml:

String getInitParameter (String name): Devuelve el valor del parámetro.

Enumeration getInitParameterNames (): Devuelve un objeto Enumeration con todos los nombres de los parámetros.

ServletContext getServletContext (): Devuelve la instancia de ServletContext del servlet actual.

Page 12: tomilloonce.files.wordpress.com  · Web view-Tema 4. Ser un Servlet-Los servlets viven al servicio del cliente. Su trabajo es coger la petición del cliente (request) y mandarle

String getServletName (): Devuelve el nombre del servlet especificado en el archivo de configuración.

javax.servlet.ServletContextEsta interface permite a los servlets obtener información sobre el ambiente en donde se están ejecutando. Toda aplicación web tiene una sola instancia de ServletContext, y la misma es accesible por todos los recursos activos de la aplicación. También se utiliza para compartir información entre servlets.Métodos de la interface:

java.net.URL getResource (String path): Devuelve una instancia de URL del recurso que apunta el path. El path debe comenzar con un carácter ‘/’ el cuál especifica el directorio raíz de la aplicación web.

java.io.InputStream getResourceAsStream (String path): Es un atajo para obtener el InputStream de salida de un recurso. Es equivalente a getResource(path).openStream().

java.lang.String getRealPath (String relativePath): Devuelve el path absoluto del recurso, es decir, su path en el sistema de archivos.

Compartiendo datos entre servletsLos servlets pueden compartir información a través de tres objetos contenedores. Los mismos difieren en la visibilidad de la información contenida.

javax.servlet.ServletRequest: Puede compartir información con cualquier servlet que se ejecute en la misma petición.

javax.servlet.http.HttpSession: Puede compartir información con cualquier servlet solo mientras sea válida la sesión del cliente.

javax.servlet.ServletContext: Puede compartir información con cualquier servlet de la misma aplicación web.

Estos tres contenedores de información poseen los siguientes métodos para setear y obtener datos:

Page 13: tomilloonce.files.wordpress.com  · Web view-Tema 4. Ser un Servlet-Los servlets viven al servicio del cliente. Su trabajo es coger la petición del cliente (request) y mandarle

Object getAttribute (String name): Devuelve el objeto almacenado o null.

Enumeration getAttributeNames (): Devuelve un objeto Enumeration que contiene los nombres de todos los atributos.

void setAttribute (String name, Object value): Agrega una pareja clave-valor al contenedor.

void removeAttribute (String name): Elimina el atributo en el contenedor.

javax.servlet.RequestDispatcherLas interfaces javax.servlet.ServletContext y javax.servlet.ServletRequest poseen un método para obtener un objeto de tipo RequestDispatcher, el método es:        public RequestDispatcher getRequestDispatcher (String path)La interface RequestDispatcher posee dos métodos:

void forward (ServletRequest request, ServletResponse response): Permite a un servlet procesar una petición parcialmente y luego pasar la petición a otro servlet para generar la respuesta final. Este método puede ser invocado solo si la respuesta no fue enviada, caso contrario se lanza la excepción IllegalStateException. Es completamente manejado en el servidor, a diferencia de HttpServletResponse.sendRedirect(String location).

void include (ServletRequest request, ServletResponse response): Permite incluir el contenido de otro recurso en la respuesta que está generando el recurso que invoca el método.

La interface ServletContext además provee un método que permite redireccionar peticiones a componentes especificando solo su nombre (el cuál se define en el archivo web.xml), en vez de utilizar una URI. Este método es:public RequestDispatcher getNamedDispatcher (String name)Existe una diferencia importante entre el método getRequestDispatcher() de ServletContext y ServletRequest. Al

Page 14: tomilloonce.files.wordpress.com  · Web view-Tema 4. Ser un Servlet-Los servlets viven al servicio del cliente. Su trabajo es coger la petición del cliente (request) y mandarle

método getRequestDispatcher() de ServletRequest se le puede pasar un path relativo, mientras que al de ServletContext no. El path pasado al método de ServletContext debe comenzar con ‘/’.

Accediendo a los atributos de la petición con RequestDispatcherEl servlet incluido o redireccionado puede acceder a la información de la petición original a través de diversos atributos. Los nombres de los atributos dependen de si se ha invocado el método forward() o include(), los mismos pueden ser:- include():

javax.servlet.include.request_uri javax.servlet.include.context_path javax.servlet.include.servlet_path javax.servlet.include.path_info javax.servlet.include.query_string

- forward(): javax.servlet.forward.request_uri javax.servlet.forward.context_path javax.servlet.forward.servlet_path javax.servlet.forward.path_info javax.servlet.forward.query_string

Los valores de estos atributos son los mismos que los métodos: getRequestURI(), getContextPath(), getServletPath(), getPathInfo() ygetQueryString de la interface HttpServletRequest. Estos atributos se acceden como los atributos regulares, a través del método getAttribute().

Page 15: tomilloonce.files.wordpress.com  · Web view-Tema 4. Ser un Servlet-Los servlets viven al servicio del cliente. Su trabajo es coger la petición del cliente (request) y mandarle

RESUMEN Ciclo de vida de un Servlet y API

El contenedor inicializa un servlet cargando su clase, invocando su constructor sin argumentos, e invocando el método init().

El método init() (el cual puede sobrescribir el programador) solo es invocado una vez en la vida del servlet, y siempre antes de que este pueda dar servicio a cualquier petición cliente.

El método init() brinda (al servlet) acceso a los objetos ServletConfig y ServletContext, los cuales el servlet necesita para obtener información sobre su propia configuración y la de la aplicación web.

El contenedor finaliza la vida de un servlet invocando su método destroy().

La mayoría del tiempo de vida de un servlet se pasa ejecutando el método service() para una petición de un cliente.

Page 16: tomilloonce.files.wordpress.com  · Web view-Tema 4. Ser un Servlet-Los servlets viven al servicio del cliente. Su trabajo es coger la petición del cliente (request) y mandarle

Cada petición a un servlet se ejecuta en un thread separado. Solo existe una instancia de una clase servlet en particular.

Los servlets deben extender (en su mayoría) de la clase javax.servlet.http.HttpServlet, es en esta clase abstracta en donde se sobrecarga el método service() para que tome como parámetros los objetos HttpServletRequest y HttpServletResponse.

HttpServlet extiende de la clase abstracta javax.servlet.GenericServlet, la cual implementa la mayoría de los métodos básicos del servlet.

La clase GenericServlet implementa las interfaces Servlet y ServletConfig.

Las clases servlets se encuentran en uno de los dos paquetes: javax.servlet y javax.sevlet.http.

Se puede sobrescribir el método init(), y se debe sobrescribir al menos un método de servicio (doGet(), doPost(), etc.).

HTTP y HttpServletRequest Los métodos doGet() y doPost() de HttpServlet toman como

argumentos los objetos HttpServletRequest y HttpServletResponse.

El método service() determina que método de servicio (doGet(), doPost(), etc.) se debe ejecutar basado en el método HTTP (GET, POST, etc.).

Las peticiones POST poseen un cuerpo, las peticiones GET no, aunque estas últimas pueden contener parámetros de petición en su URL.

Las peticiones GET son idempotentes (idempotent). Es decir, son capaces de ejecutarse múltiples veces sin causar ningún efecto en el servidor. 

Las peticiones POST no son idempotentes. Por este motivo, se debe diseñar el código de manera que si el cliente manda una misma petición dos veces  (por error), se pueda manejar de una manera correcta.

Page 17: tomilloonce.files.wordpress.com  · Web view-Tema 4. Ser un Servlet-Los servlets viven al servicio del cliente. Su trabajo es coger la petición del cliente (request) y mandarle

HttpServletResponse Los objetos Response se utilizan para enviar información de

respuesta al cliente. Los métodos que más se utilizan en el objeto de respuesta

HttpServletResponse son setContentType() y getWriter(). El método getWriter() permite realizar operaciones de escritura

de HTML (u otro tipo de texto) en el flujo de salida. En la práctica, se utilizan más las paginas JSP para enviar HTML

de respuesta, pero los servlets se pueden utilizar para enviar información binaria (como el caso de archivos) al cliente.

El método para obtener un flujo de salida binario es getOutputStream().

El método setContentType() permite indicar al browser como debe manejar la información que se envía en la respuesta. Los valores típicos son: “text/html”, “application/pdf”, y “image/jpeg”.

Se pueden setear los encabezados de respuesta utilizando los métodos addHeader() y setHeader(). La diferencia entre ambos depende es lo que se encuentra seteado en los encabezados. Es decir, setHeader() reemplaza el valor del encabezado, mientras que addHeader() agrega un valor adicional al encabezado ya existente. En caso de que el encabezado no exista ambos métodos se comportan del mismo modo.

El método sendRedirec() redirige una petición hacia otro recurso. Enviando el código 301 al browser, el cual es el que realiza la redirección al recurso especificado en la respuesta HTTP. 

No se puede invocar el método sendRedirect() una vez que la respuesta ya fue invocada al cliente. En caso de que se invoque el método en esta situación, se lanzará la excepción IllegalStateException.