# Servelts y JSP

# Leer Cabeceras de Solicitud HTTP

1. Introducción a las Cabeceras de Solicitud
2. Leer Cabeceras de Solicitud desde Servlets
3. Ejemplo: Imprimir todas la Cabeceras

## 1. Introducción a las Cabeceras de Solicitud

Cuando un cliente HTTP (por ejemplo, un navegador) envía una petición, se pide que suministre una línea de petición (normalmente GET o POST). Si se quiere también puede enviar un número de cabeceras, que son opcionales excepto Content-Length, que es requerida sólo para peticiones POST. Aquí tenemos las cabecers más comunes:

- Accept Los tipos MIME que prefiere el navegador.
- Accept-Charset El conjunto de caracteres que espera el navegador.
- Accept-Encoding Los tipos de codificación de datos (como gzip) para que el navegador sepa como decoficarlos. Los servlets pueden chequear explícitamente el soporte para gzip y devolver páginas HTML comprimidas con gzip para navegadores que las soportan, seleccionando la cabecera de respuesta Content-Encoding para indicar que están comprimidas con gzip. En muchos casos, esto puede reducir el tiempo de descarga por un factor de cinco o diez.
- Accept-Language El idioma que está esperando el navegador, en el caso de que el servidor tenga versiones en más de un idioma.
- Authorization Información de autorización, usualmente en respuesta a una cabecera WWW-Authenticate desde el servidor.
- Connection ¿Usamos conexiones persistentes? Sí un servlet obtiene un valor Keep-Alive aquí, u obtiene una línea de petición indicando HTTP 1.1 (donde las conexiones persistentes son por defecto), podría ser posible tomar ventaja de las conexiones persisentes, ahorrando un tiempo significante para las páginas Web que incluyen muchas piezas pequeñas (imágenes o clases de applets). Para hacer esto, necesita envíar una cabecera Content-Length en la respuesta, que es fácimente conseguido escribiendo en un ByteArrayOutputStream, y preguntando por el tamaño antes de escribir la salida.
- Content-Length (para mensajes POST, cúantos datos se han añadido)
- Cookie (una de las cabeceras más importantes, puedes ver la sección independiente de esta tutorial dedicada a los Cookies) .
- From (dirección email del peticionarios; sólo usado por aceleradores Web, no por clientes personalizados ni por navegadores)
- Host (host y puerto escuchado en la URL original)
- If-Modified-Since (sólo devuelve documentos más nuevos que éste, de otra form se envía una respuesta 304 "Not Modified" response)
- Pragma (el valor no-cache indica que el servidor debería devolver un documento nuevo, incluso si es un proxy con una copia local)
- Referer (la URL de la página que contiene el enlace que el usuario siguió para obtener la página actual)
- User-Agent (tipo de navegador, útil si el servlets está devolviendo contenido específico para un navegador)
- UA-Pixels, UA-Color, UA-OS, UA-CPU (cabeceras no estándard envíadas por algunas veriones de Internet Explorer, indicando el tamaño de la pantalla, la profundidad del color, el sistema operativo, y el tipo de CPU usada por el sistema del navegador)

Para ver todos los detalles sobre las cabeceras HTTP, puedes ver las especificaciones en http://www.w3.org/Protocols/.

## 2. Leer Cabeceras de Solicitud desde Servlets

Leer cabeceras es muy sencillo, sólo llamamos al método getHeader de HttpServletRequest, que devuelve un String si se suministró la cebecera en esta petición, y null si no se suministró. Sin embargo, hay un par de cabeceras que se usan de forma tan común que tienen métodos de acceso especiales. El método getCookies devuelve el contenido de la cabecera Cookie, lo analiza y lo almacena en un array de objetos Cookie. Los métodos getAuthType y getRemoteUser dividen la cabecera Authorization en su componentes. Los métodos getDateHeader y getIntHeader leen la cabecera específica y la convierten a valores Date e int, respectivamente.

En vez de buscar una cabecera particular, podemos usar el getHeaderNames para obtener una Enumeration de todos los nombres de cabecera de esta petición particular.

Finalmente, además de buscar las cabeceras de petición, podemos obtener información sobre la propia línea de petición principal. El método getMethod devuelve el método de petición principal (normalmente GET o POST, pero son posibles cosas como HEAD, PUT, y DELETE). El método getRequestURI devuelve la URI (la parte de la URL que viene después del host y el puerto, pero antes de los datos del formulario). El getRequestProtocol devuelve la tercera parte de la línea de petición que generalmente es "HTTP/1.0" o "HTTP/1.1".

## 3. Ejemplo: Imprimir todas las Cabeceras

Aquí tenemos un servelt que simplemente crea una tabla con todas las cabeceras recibidas, junto con sus valores asociados. También imprime los tres componentes de la línea de petición principal (método, URI y protocolo).

### 3.1 ShowRequestHeaders.java

También puedes descargar el código fuente

>     package hall;

>     import java.io.*;
>     import javax.servlet.*;
>     import javax.servlet.http.*;
>     import java.util.*;

>     public class ShowRequestHeaders extends HttpServlet {
>       public void doGet(HttpServletRequest request,
>                         HttpServletResponse response)
>           throws ServletException, IOException {
>         response.setContentType("text/html");
>         PrintWriter out = response.getWriter();
>         String title = "Servlet Example: Showing Request Headers";
>         out.println(ServletUtilities.headWithTitle(title) +
>                     "<BODY BGCOLOR=\"#FDF5E6\">\n" +
>                     "<H1 ALIGN=CENTER>" + title + "</H1>\n" +
>                     "<B>Request Method: </B>" +
>                     request.getMethod() + "<BR>\n" +
>                     "<B>Request URI: </B>" +
>                     request.getRequestURI() + "<BR>\n" +
>                     "<B>Request Protocol: </B>" +
>                     request.getProtocol() + "<BR><BR>\n" +
>                     "<TABLE BORDER=1 ALIGN=CENTER>\n" +
>                     "<TR BGCOLOR=\"#FFAD00\">\n" +
>                     "<TH>Header Name<TH>Header Value");
>         Enumeration headerNames = request.getHeaderNames();
>         while(headerNames.hasMoreElements()) {
>           String headerName = (String)headerNames.nextElement();
>           out.println("<TR><TD>" + headerName);
>           out.println("    <TD>" + request.getHeader(headerName));
>         }
>         out.println("</TABLE>\n</BODY></HTML>");
>       }

>       public void doPost(HttpServletRequest request,
>                          HttpServletResponse response)
>           throws ServletException, IOException {
>         doGet(request, response);
>       }
>     }

### 3.2 Salida de ShowRequestHeaders

Aquí están los resultados de dos peticiones típicas, una de Netscape y otra de Internet Explorer. Veremos la razón por la que Netscape muestra una cabecera Cookie cuando lleguemos a la sección Cookies.

Ozito